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

kubeovn / kube-ovn / 17723172333

15 Sep 2025 05:35AM UTC coverage: 21.04% (-0.2%) from 21.229%
17723172333

push

github

web-flow
fix(deps): update module github.com/puzpuzpuz/xsync/v4 to v4.2.0 (#5722)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

10661 of 50669 relevant lines covered (21.04%)

0.25 hits per line

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

8.55
/pkg/controller/admin_network_policy.go
1
package controller
2

3
import (
4
        "errors"
5
        "fmt"
6
        "net"
7
        "reflect"
8
        "strings"
9
        "unicode"
10

11
        "github.com/scylladb/go-set/strset"
12
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
13
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14
        "k8s.io/apimachinery/pkg/labels"
15
        "k8s.io/client-go/tools/cache"
16
        "k8s.io/klog/v2"
17
        v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1"
18

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

25
type ChangedField string
26

27
const (
28
        ChangedSubject     ChangedField = "Subject"
29
        ChangedIngressRule ChangedField = "IngressRule"
30
        ChangedEgressRule  ChangedField = "EgressRule"
31
)
32

33
type ChangedName struct {
34
        // the rule name can be omitted default, add isMatch to append check for rule update
35
        isMatch     bool
36
        oldRuleName string
37
        curRuleName string
38
}
39

40
type AdminNetworkPolicyChangedDelta struct {
41
        key              string
42
        ruleNames        [util.AnpMaxRules]ChangedName
43
        field            ChangedField
44
        DNSReconcileDone bool
45
}
46

47
func (c *Controller) enqueueAddAnp(obj any) {
×
48
        key := cache.MetaObjectToName(obj.(*v1alpha1.AdminNetworkPolicy)).String()
×
49
        klog.V(3).Infof("enqueue add anp %s", key)
×
50
        c.addAnpQueue.Add(key)
×
51
}
×
52

53
func (c *Controller) enqueueDeleteAnp(obj any) {
×
54
        var anp *v1alpha1.AdminNetworkPolicy
×
55
        switch t := obj.(type) {
×
56
        case *v1alpha1.AdminNetworkPolicy:
×
57
                anp = t
×
58
        case cache.DeletedFinalStateUnknown:
×
59
                a, ok := t.Obj.(*v1alpha1.AdminNetworkPolicy)
×
60
                if !ok {
×
61
                        klog.Warningf("unexpected object type: %T", t.Obj)
×
62
                        return
×
63
                }
×
64
                anp = a
×
65
        default:
×
66
                klog.Warningf("unexpected type: %T", obj)
×
67
                return
×
68
        }
69

70
        klog.V(3).Infof("enqueue delete anp %s", cache.MetaObjectToName(anp).String())
×
71
        c.deleteAnpQueue.Add(anp)
×
72
}
73

74
func (c *Controller) enqueueUpdateAnp(oldObj, newObj any) {
×
75
        oldAnpObj := oldObj.(*v1alpha1.AdminNetworkPolicy)
×
76
        newAnpObj := newObj.(*v1alpha1.AdminNetworkPolicy)
×
77

×
78
        // All the acls should be recreated with the following situations
×
79
        if oldAnpObj.Spec.Priority != newAnpObj.Spec.Priority || len(oldAnpObj.Spec.Ingress) != len(newAnpObj.Spec.Ingress) || len(oldAnpObj.Spec.Egress) != len(newAnpObj.Spec.Egress) {
×
80
                c.addAnpQueue.Add(newAnpObj.Name)
×
81
                return
×
82
        }
×
83

84
        // Acls should be updated when action or ports of ingress/egress rule has been changed
85
        for index, rule := range newAnpObj.Spec.Ingress {
×
86
                oldRule := oldAnpObj.Spec.Ingress[index]
×
87
                if oldRule.Action != rule.Action || !reflect.DeepEqual(oldRule.Ports, rule.Ports) {
×
88
                        // It's difficult to distinguish which rule has changed and update acls for that rule, so go through the anp add process to recreate acls.
×
89
                        // If we want to get fine-grained changes over rule, maybe it's a better way to add a new queue to process the change
×
90
                        c.addAnpQueue.Add(newAnpObj.Name)
×
91
                        return
×
92
                }
×
93
        }
94

95
        for index, rule := range newAnpObj.Spec.Egress {
×
96
                oldRule := oldAnpObj.Spec.Egress[index]
×
97
                if oldRule.Action != rule.Action || !reflect.DeepEqual(oldRule.Ports, rule.Ports) {
×
98
                        c.addAnpQueue.Add(newAnpObj.Name)
×
99
                        return
×
100
                }
×
101
        }
102

103
        if oldAnpObj.Annotations[util.ACLActionsLogAnnotation] != newAnpObj.Annotations[util.ACLActionsLogAnnotation] {
×
104
                c.addAnpQueue.Add(newAnpObj.Name)
×
105
                return
×
106
        }
×
107
        klog.V(3).Infof("enqueue update anp %s", newAnpObj.Name)
×
108

×
109
        // The remaining changes do not affect the acls. The port-group or address-set should be updated.
×
110
        // The port-group for anp should be updated
×
111
        if !reflect.DeepEqual(oldAnpObj.Spec.Subject, newAnpObj.Spec.Subject) {
×
112
                c.updateAnpQueue.Add(&AdminNetworkPolicyChangedDelta{key: newAnpObj.Name, field: ChangedSubject})
×
113
        }
×
114

115
        // Rule name or peer selector in ingress/egress rule has changed, the corresponding address-set need be updated
116
        ruleChanged := false
×
117
        var changedIngressRuleNames, changedEgressRuleNames [util.AnpMaxRules]ChangedName
×
118
        for index, rule := range newAnpObj.Spec.Ingress {
×
119
                oldRule := oldAnpObj.Spec.Ingress[index]
×
120
                if oldRule.Name != rule.Name {
×
121
                        changedIngressRuleNames[index] = ChangedName{oldRuleName: oldRule.Name, curRuleName: rule.Name}
×
122
                        ruleChanged = true
×
123
                }
×
124
                if !reflect.DeepEqual(oldRule.From, rule.From) {
×
125
                        changedIngressRuleNames[index] = ChangedName{curRuleName: rule.Name}
×
126
                        ruleChanged = true
×
127
                }
×
128
        }
129
        if ruleChanged {
×
130
                c.updateAnpQueue.Add(&AdminNetworkPolicyChangedDelta{key: newAnpObj.Name, ruleNames: changedIngressRuleNames, field: ChangedIngressRule})
×
131
        }
×
132

133
        ruleChanged = false
×
134
        for index, rule := range newAnpObj.Spec.Egress {
×
135
                oldRule := oldAnpObj.Spec.Egress[index]
×
136
                if oldRule.Name != rule.Name {
×
137
                        changedEgressRuleNames[index] = ChangedName{oldRuleName: oldRule.Name, curRuleName: rule.Name}
×
138
                        ruleChanged = true
×
139
                }
×
140
                if !reflect.DeepEqual(oldRule.To, rule.To) {
×
141
                        changedEgressRuleNames[index] = ChangedName{curRuleName: rule.Name}
×
142
                        ruleChanged = true
×
143
                }
×
144
        }
145
        if ruleChanged {
×
146
                c.updateAnpQueue.Add(&AdminNetworkPolicyChangedDelta{key: newAnpObj.Name, ruleNames: changedEgressRuleNames, field: ChangedEgressRule})
×
147
        }
×
148
}
149

150
func (c *Controller) handleAddAnp(key string) (err error) {
×
151
        c.anpKeyMutex.LockKey(key)
×
152
        defer func() { _ = c.anpKeyMutex.UnlockKey(key) }()
×
153

154
        cachedAnp, err := c.anpsLister.Get(key)
×
155
        if err != nil {
×
156
                if k8serrors.IsNotFound(err) {
×
157
                        return nil
×
158
                }
×
159
                klog.Error(err)
×
160
                return err
×
161
        }
162
        klog.Infof("handle add anp %s", cachedAnp.Name)
×
163
        anp := cachedAnp.DeepCopy()
×
164

×
165
        if err := c.validateAnpConfig(anp); err != nil {
×
166
                klog.Errorf("failed to validate anp %s: %v", anp.Name, err)
×
167
                return err
×
168
        }
×
169
        if priority, exist := c.anpNamePrioMap[anp.Name]; exist && priority != anp.Spec.Priority {
×
170
                // anp spec's priority has been changed
×
171
                delete(c.anpPrioNameMap, priority)
×
172
        }
×
173
        // record new created anp after validation
174
        c.anpPrioNameMap[anp.Spec.Priority] = anp.Name
×
175
        c.anpNamePrioMap[anp.Name] = anp.Spec.Priority
×
176

×
177
        anpName := getAnpName(anp.Name)
×
178
        var logActions []string
×
179
        if anp.Annotations[util.ACLActionsLogAnnotation] != "" {
×
180
                logActions = strings.Split(anp.Annotations[util.ACLActionsLogAnnotation], ",")
×
181
        }
×
182

183
        // ovn portGroup/addressSet doesn't support name with '-', so we replace '-' by '.'.
184
        // This may cause conflict if two anp with name test-anp and test.anp, maybe hash is a better solution, but we do not want to lost the readability now.
185
        // Make sure all create operations are reentrant.
186
        pgName := strings.ReplaceAll(anpName, "-", ".")
×
187
        if err = c.OVNNbClient.CreatePortGroup(pgName, map[string]string{adminNetworkPolicyKey: anpName}); err != nil {
×
188
                klog.Errorf("failed to create port group for anp %s: %v", key, err)
×
189
                return err
×
190
        }
×
191

192
        ports, err := c.fetchSelectedPods(&anp.Spec.Subject)
×
193
        if err != nil {
×
194
                klog.Errorf("failed to fetch ports belongs to anp %s: %v", key, err)
×
195
                return err
×
196
        }
×
197

198
        if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil {
×
199
                klog.Errorf("failed to set ports %v to port group %s: %v", ports, pgName, err)
×
200
                return err
×
201
        }
×
202

203
        ingressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "to-lport", nil)
×
204
        if err != nil {
×
205
                klog.Errorf("failed to generate clear operations for anp %s ingress acls: %v", key, err)
×
206
                return err
×
207
        }
×
208

209
        curIngressAddrSet, curEgressAddrSet, err := c.getCurrentAddrSetByName(anpName, false)
×
210
        if err != nil {
×
211
                klog.Errorf("failed to list address sets for anp %s: %v", key, err)
×
212
                return err
×
213
        }
×
214
        desiredIngressAddrSet := strset.NewWithSize(len(anp.Spec.Ingress) * 2)
×
215
        desiredEgressAddrSet := strset.NewWithSize(len(anp.Spec.Egress) * 2)
×
216

×
217
        // create ingress acl
×
218
        for index, anpr := range anp.Spec.Ingress {
×
219
                // 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
×
220
                ingressAsV4Name, ingressAsV6Name := getAnpAddressSetName(pgName, anpr.Name, index, true)
×
221
                desiredIngressAddrSet.Add(ingressAsV4Name, ingressAsV6Name)
×
222

×
223
                var v4Addrs, v4Addr, v6Addrs, v6Addr []string
×
224
                // This field must be defined and contain at least one item.
×
225
                for _, anprpeer := range anpr.From {
×
226
                        if v4Addr, v6Addr, err = c.fetchIngressSelectedAddresses(&anprpeer); err != nil {
×
227
                                klog.Errorf("failed to fetch admin network policy selected addresses, %v", err)
×
228
                                return err
×
229
                        }
×
230
                        v4Addrs = append(v4Addrs, v4Addr...)
×
231
                        v6Addrs = append(v6Addrs, v6Addr...)
×
232
                }
233
                klog.Infof("anp %s, ingress rule %s, selected v4 address %v, v6 address %v", anpName, anpr.Name, v4Addrs, v6Addrs)
×
234

×
235
                if err = c.createAsForAnpRule(anpName, anpr.Name, "ingress", ingressAsV4Name, v4Addrs, false); err != nil {
×
236
                        klog.Error(err)
×
237
                        return err
×
238
                }
×
239
                if err = c.createAsForAnpRule(anpName, anpr.Name, "ingress", ingressAsV6Name, v6Addrs, false); err != nil {
×
240
                        klog.Error(err)
×
241
                        return err
×
242
                }
×
243

244
                aclPriority := util.AnpACLMaxPriority - int(anp.Spec.Priority*100) - index
×
245
                aclAction := anpACLAction(anpr.Action)
×
246
                rulePorts := []v1alpha1.AdminNetworkPolicyPort{}
×
247
                if anpr.Ports != nil {
×
248
                        rulePorts = *anpr.Ports
×
249
                }
×
250

251
                if len(v4Addrs) != 0 {
×
252
                        aclName := fmt.Sprintf("anp/%s/ingress/%s/%d", anpName, kubeovnv1.ProtocolIPv4, index)
×
253
                        ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, ingressAsV4Name, kubeovnv1.ProtocolIPv4, aclName, aclPriority, aclAction, logActions, rulePorts, true, false)
×
254
                        if err != nil {
×
255
                                klog.Errorf("failed to add v4 ingress acls for anp %s: %v", key, err)
×
256
                                return err
×
257
                        }
×
258
                        ingressACLOps = append(ingressACLOps, ops...)
×
259
                }
260

261
                if len(v6Addrs) != 0 {
×
262
                        aclName := fmt.Sprintf("anp/%s/ingress/%s/%d", anpName, kubeovnv1.ProtocolIPv6, index)
×
263
                        ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, ingressAsV6Name, kubeovnv1.ProtocolIPv6, aclName, aclPriority, aclAction, logActions, rulePorts, true, false)
×
264
                        if err != nil {
×
265
                                klog.Errorf("failed to add v6 ingress acls for anp %s: %v", key, err)
×
266
                                return err
×
267
                        }
×
268
                        ingressACLOps = append(ingressACLOps, ops...)
×
269
                }
270
        }
271

272
        if err := c.OVNNbClient.Transact("add-ingress-acls", ingressACLOps); err != nil {
×
273
                return fmt.Errorf("failed to add ingress acls for anp %s: %w", key, err)
×
274
        }
×
275
        if err := c.deleteUnusedAddrSetForAnp(curIngressAddrSet, desiredIngressAddrSet); err != nil {
×
276
                return fmt.Errorf("failed to delete unused ingress address set for anp %s: %w", key, err)
×
277
        }
×
278

279
        egressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "from-lport", nil)
×
280
        if err != nil {
×
281
                klog.Errorf("failed to generate clear operations for anp %s egress acls: %v", key, err)
×
282
                return err
×
283
        }
×
284

285
        // Reconcile DNSNameResolvers for all collected domain names
286
        if c.config.EnableDNSNameResolver {
×
287
                // Collect all domain names from egress rules
×
288
                var allDomainNames []string
×
289
                for _, anpr := range anp.Spec.Egress {
×
290
                        for _, anprpeer := range anpr.To {
×
291
                                if len(anprpeer.DomainNames) != 0 {
×
292
                                        for _, domainName := range anprpeer.DomainNames {
×
293
                                                allDomainNames = append(allDomainNames, string(domainName))
×
294
                                        }
×
295
                                }
296
                        }
297
                }
298

299
                if err := c.reconcileDNSNameResolversForANP(anpName, allDomainNames); err != nil {
×
300
                        klog.Errorf("failed to reconcile DNSNameResolvers for ANP %s: %v", anpName, err)
×
301
                        return err
×
302
                }
×
303
        }
304

305
        // create egress acl
306
        for index, anpr := range anp.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
                egressAsV4Name, egressAsV6Name := getAnpAddressSetName(pgName, anpr.Name, index, false)
×
309
                desiredEgressAddrSet.Add(egressAsV4Name, egressAsV6Name)
×
310

×
311
                var v4Addrs, v4Addr, v6Addrs, v6Addr []string
×
312
                hasDomainNames := false
×
313
                // This field must be defined and contain at least one item.
×
314
                for _, anprpeer := range anpr.To {
×
315
                        if v4Addr, v6Addr, err = c.fetchEgressSelectedAddresses(&anprpeer); err != nil {
×
316
                                klog.Errorf("failed to fetch admin network policy selected addresses, %v", err)
×
317
                                return err
×
318
                        }
×
319
                        v4Addrs = append(v4Addrs, v4Addr...)
×
320
                        v6Addrs = append(v6Addrs, v6Addr...)
×
321

×
322
                        // Check if this peer has domain names
×
323
                        hasDomainNames = len(anprpeer.DomainNames) > 0
×
324
                }
325
                klog.Infof("anp %s, egress rule %s, selected v4 address %v, v6 address %v", anpName, anpr.Name, v4Addrs, v6Addrs)
×
326

×
327
                if err = c.createAsForAnpRule(anpName, anpr.Name, "egress", egressAsV4Name, v4Addrs, false); err != nil {
×
328
                        klog.Error(err)
×
329
                        return err
×
330
                }
×
331
                if err = c.createAsForAnpRule(anpName, anpr.Name, "egress", egressAsV6Name, v6Addrs, false); err != nil {
×
332
                        klog.Error(err)
×
333
                        return err
×
334
                }
×
335

336
                aclPriority := util.AnpACLMaxPriority - int(anp.Spec.Priority*100) - index
×
337
                aclAction := anpACLAction(anpr.Action)
×
338
                rulePorts := []v1alpha1.AdminNetworkPolicyPort{}
×
339
                if anpr.Ports != nil {
×
340
                        rulePorts = *anpr.Ports
×
341
                }
×
342

343
                // Create ACL rules if we have IP addresses OR domain names
344
                // Domain names may not be resolved initially but will be updated later
345
                if len(v4Addrs) != 0 || hasDomainNames {
×
346
                        aclName := fmt.Sprintf("anp/%s/egress/%s/%d", anpName, kubeovnv1.ProtocolIPv4, index)
×
347
                        ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, egressAsV4Name, kubeovnv1.ProtocolIPv4, aclName, aclPriority, aclAction, logActions, rulePorts, false, false)
×
348
                        if err != nil {
×
349
                                klog.Errorf("failed to add v4 egress acls for anp %s: %v", key, err)
×
350
                                return err
×
351
                        }
×
352
                        egressACLOps = append(egressACLOps, ops...)
×
353
                }
354

355
                if len(v6Addrs) != 0 || hasDomainNames {
×
356
                        aclName := fmt.Sprintf("anp/%s/egress/%s/%d", anpName, kubeovnv1.ProtocolIPv6, index)
×
357
                        ops, err := c.OVNNbClient.UpdateAnpRuleACLOps(pgName, egressAsV6Name, kubeovnv1.ProtocolIPv6, aclName, aclPriority, aclAction, logActions, rulePorts, false, false)
×
358
                        if err != nil {
×
359
                                klog.Errorf("failed to add v6 egress acls for anp %s: %v", key, err)
×
360
                                return err
×
361
                        }
×
362
                        egressACLOps = append(egressACLOps, ops...)
×
363
                }
364
        }
365

366
        if err := c.OVNNbClient.Transact("add-egress-acls", egressACLOps); err != nil {
×
367
                return fmt.Errorf("failed to add egress acls for anp %s: %w", key, err)
×
368
        }
×
369
        if err := c.deleteUnusedAddrSetForAnp(curEgressAddrSet, desiredEgressAddrSet); err != nil {
×
370
                return fmt.Errorf("failed to delete unused egress address set for anp %s: %w", key, err)
×
371
        }
×
372

373
        return nil
×
374
}
375

376
func (c *Controller) handleDeleteAnp(anp *v1alpha1.AdminNetworkPolicy) error {
×
377
        c.anpKeyMutex.LockKey(anp.Name)
×
378
        defer func() { _ = c.anpKeyMutex.UnlockKey(anp.Name) }()
×
379

380
        klog.Infof("handle delete admin network policy %s", anp.Name)
×
381
        delete(c.anpPrioNameMap, anp.Spec.Priority)
×
382
        delete(c.anpNamePrioMap, anp.Name)
×
383

×
384
        anpName := getAnpName(anp.Name)
×
385

×
386
        // ACLs releated to port_group will be deleted automatically when port_group is deleted
×
387
        pgName := strings.ReplaceAll(anpName, "-", ".")
×
388
        if err := c.OVNNbClient.DeletePortGroup(pgName); err != nil {
×
389
                klog.Errorf("failed to delete port group for anp %s: %v", anpName, err)
×
390
        }
×
391

392
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
393
                adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "ingress"),
×
394
        }); err != nil {
×
395
                klog.Errorf("failed to delete ingress address set for anp %s: %v", anpName, err)
×
396
                return err
×
397
        }
×
398

399
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
400
                adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "egress"),
×
401
        }); err != nil {
×
402
                klog.Errorf("failed to delete egress address set for anp %s: %v", anpName, err)
×
403
                return err
×
404
        }
×
405

406
        // Delete all DNSNameResolver CRs associated with this ANP
407
        if c.config.EnableDNSNameResolver {
×
408
                if err := c.reconcileDNSNameResolversForANP(anpName, []string{}); err != nil {
×
409
                        klog.Errorf("failed to delete DNSNameResolver CRs for anp %s: %v", anpName, err)
×
410
                        return err
×
411
                }
×
412
        }
413

414
        return nil
×
415
}
416

417
func (c *Controller) handleUpdateAnp(changed *AdminNetworkPolicyChangedDelta) error {
×
418
        // Only handle updates that do not affect acls.
×
419
        c.anpKeyMutex.LockKey(changed.key)
×
420
        defer func() { _ = c.anpKeyMutex.UnlockKey(changed.key) }()
×
421

422
        klog.Infof("handleUpdateAnp: processing ANP %s, field=%s, DNSReconcileDone=%v",
×
423
                changed.key, changed.field, changed.DNSReconcileDone)
×
424

×
425
        cachedAnp, err := c.anpsLister.Get(changed.key)
×
426
        if err != nil {
×
427
                if k8serrors.IsNotFound(err) {
×
428
                        return nil
×
429
                }
×
430
                klog.Error(err)
×
431
                return err
×
432
        }
433
        desiredAnp := cachedAnp.DeepCopy()
×
434
        klog.Infof("handle update admin network policy %s", desiredAnp.Name)
×
435

×
436
        anpName := getAnpName(desiredAnp.Name)
×
437
        pgName := strings.ReplaceAll(anpName, "-", ".")
×
438

×
439
        // The port-group for anp should be updated
×
440
        if changed.field == ChangedSubject {
×
441
                // The port-group must exist when update anp, this check should never be matched.
×
442
                if ok, err := c.OVNNbClient.PortGroupExists(pgName); !ok || err != nil {
×
443
                        klog.Errorf("port-group for anp %s does not exist when update anp", desiredAnp.Name)
×
444
                        return err
×
445
                }
×
446

447
                ports, err := c.fetchSelectedPods(&desiredAnp.Spec.Subject)
×
448
                if err != nil {
×
449
                        klog.Errorf("failed to fetch ports belongs to anp %s: %v", desiredAnp.Name, err)
×
450
                        return err
×
451
                }
×
452

453
                if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil {
×
454
                        klog.Errorf("failed to set ports %v to port group %s: %v", ports, pgName, err)
×
455
                        return err
×
456
                }
×
457
        }
458

459
        // Peer selector in ingress/egress rule has changed, so the corresponding address-set need be updated
460
        if changed.field == ChangedIngressRule {
×
461
                for index, rule := range desiredAnp.Spec.Ingress {
×
462
                        // Make sure the rule is changed and go on update
×
463
                        if rule.Name == changed.ruleNames[index].curRuleName || changed.ruleNames[index].isMatch {
×
464
                                if err := c.setAddrSetForAnpRule(anpName, pgName, rule.Name, index, rule.From, []v1alpha1.AdminNetworkPolicyEgressPeer{}, true, false); err != nil {
×
465
                                        klog.Errorf("failed to set ingress address-set for anp rule %s/%s, %v", anpName, rule.Name, err)
×
466
                                        return err
×
467
                                }
×
468

469
                                if changed.ruleNames[index].oldRuleName != "" {
×
470
                                        oldRuleName := changed.ruleNames[index].oldRuleName
×
471
                                        // Normally the name can not be changed, but when the name really changes, the old address set should be deleted
×
472
                                        // There is no description in the Name comments that it cannot be changed
×
473
                                        oldAsV4Name, oldAsV6Name := getAnpAddressSetName(pgName, oldRuleName, index, true)
×
474

×
475
                                        if err := c.OVNNbClient.DeleteAddressSet(oldAsV4Name); err != nil {
×
476
                                                klog.Errorf("failed to delete address set %s, %v", oldAsV4Name, err)
×
477
                                                // just record error log
×
478
                                        }
×
479
                                        if err := c.OVNNbClient.DeleteAddressSet(oldAsV6Name); err != nil {
×
480
                                                klog.Errorf("failed to delete address set %s, %v", oldAsV6Name, err)
×
481
                                        }
×
482
                                }
483
                        }
484
                }
485
        }
486

487
        if changed.field == ChangedEgressRule {
×
488
                for index, rule := range desiredAnp.Spec.Egress {
×
489
                        // Check if we need to update address sets (rule changed or DNS reconciliation needed)
×
490
                        needAddrSetUpdate := rule.Name == changed.ruleNames[index].curRuleName || changed.ruleNames[index].isMatch || changed.DNSReconcileDone
×
491

×
492
                        // Check if we need to reconcile DNS resolvers (DNS feature enabled and not already done)
×
493
                        needDNSReconcile := c.config.EnableDNSNameResolver && !changed.DNSReconcileDone
×
494

×
495
                        if needAddrSetUpdate {
×
496
                                if err := c.setAddrSetForAnpRule(anpName, pgName, rule.Name, index, []v1alpha1.AdminNetworkPolicyIngressPeer{}, rule.To, false, false); err != nil {
×
497
                                        klog.Errorf("failed to set egress address-set for anp rule %s/%s, %v", anpName, rule.Name, err)
×
498
                                        return err
×
499
                                }
×
500

501
                                if needDNSReconcile {
×
502
                                        var currentDomainNames []string
×
503
                                        for _, peer := range rule.To {
×
504
                                                for _, domainName := range peer.DomainNames {
×
505
                                                        currentDomainNames = append(currentDomainNames, string(domainName))
×
506
                                                }
×
507
                                        }
508

509
                                        if err := c.reconcileDNSNameResolversForANP(anpName, currentDomainNames); err != nil {
×
510
                                                klog.Errorf("failed to reconcile DNSNameResolvers for egress rule %s/%s, %v", anpName, rule.Name, err)
×
511
                                                return err
×
512
                                        }
×
513
                                }
514

515
                                if changed.ruleNames[index].oldRuleName != "" {
×
516
                                        oldRuleName := changed.ruleNames[index].oldRuleName
×
517
                                        // Normally the name can not be changed, but when the name really changes, the old address set should be deleted
×
518
                                        // There is no description in the Name comments that it cannot be changed
×
519
                                        oldAsV4Name, oldAsV6Name := getAnpAddressSetName(pgName, oldRuleName, index, false)
×
520

×
521
                                        if err := c.OVNNbClient.DeleteAddressSet(oldAsV4Name); err != nil {
×
522
                                                klog.Errorf("failed to delete address set %s, %v", oldAsV4Name, err)
×
523
                                                // just record error log
×
524
                                        }
×
525
                                        if err := c.OVNNbClient.DeleteAddressSet(oldAsV6Name); err != nil {
×
526
                                                klog.Errorf("failed to delete address set %s, %v", oldAsV6Name, err)
×
527
                                        }
×
528
                                }
529
                        }
530
                }
531
        }
532

533
        return nil
×
534
}
535

536
func (c *Controller) validateAnpConfig(anp *v1alpha1.AdminNetworkPolicy) error {
1✔
537
        // The behavior is undefined if two ANP objects have same priority.
1✔
538
        if anpName, exist := c.anpPrioNameMap[anp.Spec.Priority]; exist && anpName != anp.Name {
2✔
539
                err := fmt.Errorf("can not create anp with same priority %d, exist one is %s, new created is %s", anp.Spec.Priority, anpName, anp.Name)
1✔
540
                klog.Error(err)
1✔
541
                return err
1✔
542
        }
1✔
543

544
        // We have noticed redhat's discussion about ACL priority in https://bugzilla.redhat.com/show_bug.cgi?id=2175752
545
        // After discussion, we decided to use the same range of priorities(20000-30000). Pay tribute to the developers of redhat.
546
        if anp.Spec.Priority > util.AnpMaxPriority {
2✔
547
                err := fmt.Errorf("the priority of anp %s is greater than max value %d", anp.Name, util.AnpMaxPriority)
1✔
548
                klog.Error(err)
1✔
549
                return err
1✔
550
        }
1✔
551

552
        if len(anp.Spec.Ingress) > util.AnpMaxRules || len(anp.Spec.Egress) > util.AnpMaxRules {
1✔
553
                err := fmt.Errorf("at most %d rules can be create in anp ingress/egress, ingress rules num %d and egress rules num %d in anp %s", util.AnpMaxRules, len(anp.Spec.Ingress), len(anp.Spec.Egress), anp.Name)
×
554
                klog.Error(err)
×
555
                return err
×
556
        }
×
557

558
        return nil
1✔
559
}
560

561
func (c *Controller) fetchSelectedPods(anpSubject *v1alpha1.AdminNetworkPolicySubject) ([]string, error) {
×
562
        var ports []string
×
563

×
564
        // Exactly one field must be set.
×
565
        if anpSubject.Namespaces != nil {
×
566
                nsSelector, err := metav1.LabelSelectorAsSelector(anpSubject.Namespaces)
×
567
                if err != nil {
×
568
                        return nil, fmt.Errorf("error creating ns label selector, %w", err)
×
569
                }
×
570

571
                ports, _, _, err = c.fetchPods(nsSelector, labels.Everything())
×
572
                if err != nil {
×
573
                        return nil, fmt.Errorf("failed to fetch pods, %w", err)
×
574
                }
×
575
        } else if anpSubject.Pods != nil {
×
576
                nsSelector, err := metav1.LabelSelectorAsSelector(&anpSubject.Pods.NamespaceSelector)
×
577
                if err != nil {
×
578
                        return nil, fmt.Errorf("error creating ns label selector, %w", err)
×
579
                }
×
580
                podSelector, err := metav1.LabelSelectorAsSelector(&anpSubject.Pods.PodSelector)
×
581
                if err != nil {
×
582
                        return nil, fmt.Errorf("error creating pod label selector, %w", err)
×
583
                }
×
584

585
                ports, _, _, err = c.fetchPods(nsSelector, podSelector)
×
586
                if err != nil {
×
587
                        return nil, fmt.Errorf("failed to fetch pods, %w", err)
×
588
                }
×
589
        }
590
        klog.Infof("get selected ports for subject, %v", ports)
×
591
        return ports, nil
×
592
}
593

594
func (c *Controller) fetchPods(nsSelector, podSelector labels.Selector) ([]string, []string, []string, error) {
×
595
        ports := make([]string, 0, util.AnpMaxRules)
×
596
        v4Addresses := make([]string, 0, util.AnpMaxRules)
×
597
        v6Addresses := make([]string, 0, util.AnpMaxRules)
×
598

×
599
        namespaces, err := c.namespacesLister.List(nsSelector)
×
600
        if err != nil {
×
601
                klog.Errorf("failed to list namespaces: %v", err)
×
602
                return nil, nil, nil, err
×
603
        }
×
604

605
        klog.V(3).Infof("fetch pod ports/addresses, namespace selector is %s, pod selector is %s", nsSelector.String(), podSelector.String())
×
606
        for _, namespace := range namespaces {
×
607
                pods, err := c.podsLister.Pods(namespace.Name).List(podSelector)
×
608
                if err != nil {
×
609
                        return nil, nil, nil, fmt.Errorf("failed to list pods, %w", err)
×
610
                }
×
611

612
                for _, pod := range pods {
×
613
                        if pod.Spec.HostNetwork {
×
614
                                continue
×
615
                        }
616
                        podName := c.getNameByPod(pod)
×
617

×
618
                        podNets, err := c.getPodKubeovnNets(pod)
×
619
                        if err != nil {
×
620
                                return nil, nil, nil, fmt.Errorf("failed to get pod networks, %w", err)
×
621
                        }
×
622

623
                        for _, podNet := range podNets {
×
624
                                if !isOvnSubnet(podNet.Subnet) {
×
625
                                        continue
×
626
                                }
627

628
                                if pod.Annotations[fmt.Sprintf(util.AllocatedAnnotationTemplate, podNet.ProviderName)] == "true" {
×
629
                                        ports = append(ports, ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName))
×
630

×
631
                                        podIPAnnotation := pod.Annotations[fmt.Sprintf(util.IPAddressAnnotationTemplate, podNet.ProviderName)]
×
632
                                        podIPs := strings.SplitSeq(podIPAnnotation, ",")
×
633
                                        for podIP := range podIPs {
×
634
                                                switch util.CheckProtocol(podIP) {
×
635
                                                case kubeovnv1.ProtocolIPv4:
×
636
                                                        v4Addresses = append(v4Addresses, podIP)
×
637
                                                case kubeovnv1.ProtocolIPv6:
×
638
                                                        v6Addresses = append(v6Addresses, podIP)
×
639
                                                }
640
                                        }
641
                                }
642
                        }
643
                }
644
        }
645

646
        return ports, v4Addresses, v6Addresses, nil
×
647
}
648

649
func (c *Controller) fetchIngressSelectedAddresses(ingressPeer *v1alpha1.AdminNetworkPolicyIngressPeer) ([]string, []string, error) {
×
650
        var v4Addresses, v6Addresses []string
×
651

×
652
        // Exactly one of the selector pointers must be set for a given peer.
×
653
        if ingressPeer.Namespaces != nil {
×
654
                nsSelector, err := metav1.LabelSelectorAsSelector(ingressPeer.Namespaces)
×
655
                if err != nil {
×
656
                        return nil, nil, fmt.Errorf("error creating ns label selector, %w", err)
×
657
                }
×
658

659
                _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, labels.Everything())
×
660
                if err != nil {
×
661
                        return nil, nil, fmt.Errorf("failed to fetch ingress peer addresses, %w", err)
×
662
                }
×
663
        } else if ingressPeer.Pods != nil {
×
664
                nsSelector, err := metav1.LabelSelectorAsSelector(&ingressPeer.Pods.NamespaceSelector)
×
665
                if err != nil {
×
666
                        return nil, nil, fmt.Errorf("error creating ns label selector, %w", err)
×
667
                }
×
668
                podSelector, err := metav1.LabelSelectorAsSelector(&ingressPeer.Pods.PodSelector)
×
669
                if err != nil {
×
670
                        return nil, nil, fmt.Errorf("error creating pod label selector, %w", err)
×
671
                }
×
672

673
                _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, podSelector)
×
674
                if err != nil {
×
675
                        return nil, nil, fmt.Errorf("failed to fetch ingress peer addresses, %w", err)
×
676
                }
×
677
        }
678

679
        return v4Addresses, v6Addresses, nil
×
680
}
681

682
func (c *Controller) fetchEgressSelectedAddresses(egressPeer *v1alpha1.AdminNetworkPolicyEgressPeer) ([]string, []string, error) {
×
683
        return c.fetchEgressSelectedAddressesCommon(egressPeer.Namespaces, egressPeer.Pods, egressPeer.Nodes, egressPeer.Networks, egressPeer.DomainNames)
×
684
}
×
685

686
func (c *Controller) fetchBaselineEgressSelectedAddresses(egressPeer *v1alpha1.BaselineAdminNetworkPolicyEgressPeer) ([]string, []string, error) {
×
687
        return c.fetchEgressSelectedAddressesCommon(egressPeer.Namespaces, egressPeer.Pods, egressPeer.Nodes, egressPeer.Networks, nil)
×
688
}
×
689

690
func (c *Controller) fetchEgressSelectedAddressesCommon(namespaces *metav1.LabelSelector, pods *v1alpha1.NamespacedPod, nodes *metav1.LabelSelector, networks []v1alpha1.CIDR, domainNames []v1alpha1.DomainName) ([]string, []string, error) {
×
691
        var v4Addresses, v6Addresses []string
×
692

×
693
        // Exactly one of the selector pointers must be set for a given peer.
×
694
        switch {
×
695
        case namespaces != nil:
×
696
                nsSelector, err := metav1.LabelSelectorAsSelector(namespaces)
×
697
                if err != nil {
×
698
                        return nil, nil, fmt.Errorf("error creating ns label selector, %w", err)
×
699
                }
×
700

701
                _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, labels.Everything())
×
702
                if err != nil {
×
703
                        return nil, nil, fmt.Errorf("failed to fetch egress peer addresses, %w", err)
×
704
                }
×
705
        case pods != nil:
×
706
                nsSelector, err := metav1.LabelSelectorAsSelector(&pods.NamespaceSelector)
×
707
                if err != nil {
×
708
                        return nil, nil, fmt.Errorf("error creating ns label selector, %w", err)
×
709
                }
×
710
                podSelector, err := metav1.LabelSelectorAsSelector(&pods.PodSelector)
×
711
                if err != nil {
×
712
                        return nil, nil, fmt.Errorf("error creating pod label selector, %w", err)
×
713
                }
×
714

715
                _, v4Addresses, v6Addresses, err = c.fetchPods(nsSelector, podSelector)
×
716
                if err != nil {
×
717
                        return nil, nil, fmt.Errorf("failed to fetch egress peer addresses, %w", err)
×
718
                }
×
719
        case nodes != nil:
×
720
                nodesSelector, err := metav1.LabelSelectorAsSelector(nodes)
×
721
                if err != nil {
×
722
                        return nil, nil, fmt.Errorf("error creating nodes label selector, %w", err)
×
723
                }
×
724
                v4Addresses, v6Addresses, err = c.fetchNodesAddrs(nodesSelector)
×
725
                if err != nil {
×
726
                        return nil, nil, fmt.Errorf("failed to fetch egress peer addresses, %w", err)
×
727
                }
×
728
        case len(networks) != 0:
×
729
                v4Addresses, v6Addresses = fetchCIDRAddrs(networks)
×
730
        case len(domainNames) != 0:
×
731
                // DomainNames field is present - resolve addresses from DNSNameResolver
×
732
                if !c.config.EnableDNSNameResolver {
×
733
                        return nil, nil, fmt.Errorf("DNSNameResolver is disabled but domain names are specified: %v", domainNames)
×
734
                }
×
735
                klog.Infof("DomainNames detected in egress peer: %v", domainNames)
×
736
                var err error
×
737
                v4Addresses, v6Addresses, err = c.resolveDomainNames(domainNames)
×
738
                if err != nil {
×
739
                        return nil, nil, fmt.Errorf("failed to resolve domain names: %w", err)
×
740
                }
×
741
        default:
×
742
                return nil, nil, errors.New("at least one egressPeer must be specified")
×
743
        }
744

745
        return v4Addresses, v6Addresses, nil
×
746
}
747

748
// resolveDomainNames resolves domain names to IP addresses using DNSNameResolver lister
749
func (c *Controller) resolveDomainNames(domainNames []v1alpha1.DomainName) ([]string, []string, error) {
×
750
        var allV4Addresses, allV6Addresses []string
×
751

×
752
        for _, domainName := range domainNames {
×
753
                // Find DNSNameResolver for this domain name
×
754
                dnsNameResolvers, err := c.dnsNameResolversLister.List(labels.Everything())
×
755
                if err != nil {
×
756
                        klog.Errorf("Failed to list DNSNameResolvers: %v", err)
×
757
                        continue
×
758
                }
759

760
                var foundResolver *kubeovnv1.DNSNameResolver
×
761
                for _, resolver := range dnsNameResolvers {
×
762
                        if string(resolver.Spec.Name) == string(domainName) {
×
763
                                foundResolver = resolver
×
764
                                break
×
765
                        }
766
                }
767

768
                if foundResolver == nil {
×
769
                        klog.V(3).Infof("No DNSNameResolver found for domain %s, skipping", domainName)
×
770
                        continue
×
771
                }
772

773
                // Get resolved addresses from DNSNameResolver
774
                v4Addresses, v6Addresses, err := getResolvedAddressesFromDNSNameResolver(foundResolver)
×
775
                if err != nil {
×
776
                        klog.Errorf("Failed to get resolved addresses from DNSNameResolver %s: %v", foundResolver.Name, err)
×
777
                        continue
×
778
                }
779

780
                allV4Addresses = append(allV4Addresses, v4Addresses...)
×
781
                allV6Addresses = append(allV6Addresses, v6Addresses...)
×
782
        }
783

784
        return allV4Addresses, allV6Addresses, nil
×
785
}
786

787
func (c *Controller) createAsForAnpRule(anpName, ruleName, direction, asName string, addresses []string, isBanp bool) error {
×
788
        var err error
×
789
        if isBanp {
×
790
                err = c.OVNNbClient.CreateAddressSet(asName, map[string]string{
×
791
                        baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, direction),
×
792
                })
×
793
        } else {
×
794
                err = c.OVNNbClient.CreateAddressSet(asName, map[string]string{
×
795
                        adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, direction),
×
796
                })
×
797
        }
×
798
        if err != nil {
×
799
                klog.Errorf("failed to create ovn address set %s for anp/banp rule %s/%s: %v", asName, anpName, ruleName, err)
×
800
                return err
×
801
        }
×
802

803
        if err := c.OVNNbClient.AddressSetUpdateAddress(asName, addresses...); err != nil {
×
804
                klog.Errorf("failed to set addresses %q to address set %s: %v", strings.Join(addresses, ","), asName, err)
×
805
                return err
×
806
        }
×
807

808
        return nil
×
809
}
810

811
func (c *Controller) getCurrentAddrSetByName(anpName string, isBanp bool) (*strset.Set, *strset.Set, error) {
×
812
        curIngressAddrSet := strset.New()
×
813
        curEgressAddrSet := strset.New()
×
814
        var ass []ovnnb.AddressSet
×
815
        var err error
×
816

×
817
        // anp and banp can use same name, so depends on the external_ids key field to distinguish
×
818
        if isBanp {
×
819
                ass, err = c.OVNNbClient.ListAddressSets(map[string]string{
×
820
                        baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "ingress"),
×
821
                })
×
822
        } else {
×
823
                ass, err = c.OVNNbClient.ListAddressSets(map[string]string{
×
824
                        adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "ingress"),
×
825
                })
×
826
        }
×
827
        if err != nil {
×
828
                klog.Errorf("failed to list ingress address sets for anp/banp %s: %v", anpName, err)
×
829
                return curIngressAddrSet, curEgressAddrSet, err
×
830
        }
×
831
        for _, as := range ass {
×
832
                curIngressAddrSet.Add(as.Name)
×
833
        }
×
834

835
        if isBanp {
×
836
                ass, err = c.OVNNbClient.ListAddressSets(map[string]string{
×
837
                        baselineAdminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "egress"),
×
838
                })
×
839
        } else {
×
840
                ass, err = c.OVNNbClient.ListAddressSets(map[string]string{
×
841
                        adminNetworkPolicyKey: fmt.Sprintf("%s/%s", anpName, "egress"),
×
842
                })
×
843
        }
×
844
        if err != nil {
×
845
                klog.Errorf("failed to list egress address sets for anp/banp %s: %v", anpName, err)
×
846
                return curIngressAddrSet, curEgressAddrSet, err
×
847
        }
×
848
        for _, as := range ass {
×
849
                curEgressAddrSet.Add(as.Name)
×
850
        }
×
851

852
        return curIngressAddrSet, curEgressAddrSet, nil
×
853
}
854

855
func (c *Controller) deleteUnusedAddrSetForAnp(curAddrSet, desiredAddrSet *strset.Set) error {
×
856
        toDel := strset.Difference(curAddrSet, desiredAddrSet).List()
×
857

×
858
        for _, asName := range toDel {
×
859
                if err := c.OVNNbClient.DeleteAddressSet(asName); err != nil {
×
860
                        klog.Errorf("failed to delete address set %s, %v", asName, err)
×
861
                        return err
×
862
                }
×
863
        }
864

865
        return nil
×
866
}
867

868
func (c *Controller) setAddrSetForAnpRule(anpName, pgName, ruleName string, index int, from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.AdminNetworkPolicyEgressPeer, isIngress, isBanp bool) error {
×
869
        return c.setAddrSetForAnpRuleCommon(anpName, pgName, ruleName, index, from, to, nil, isIngress, isBanp)
×
870
}
×
871

872
func (c *Controller) setAddrSetForBaselineAnpRule(anpName, pgName, ruleName string, index int, from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.BaselineAdminNetworkPolicyEgressPeer, isIngress, isBanp bool) error {
×
873
        return c.setAddrSetForAnpRuleCommon(anpName, pgName, ruleName, index, from, nil, to, isIngress, isBanp)
×
874
}
×
875

876
func (c *Controller) setAddrSetForAnpRuleCommon(anpName, pgName, ruleName string, index int, from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.AdminNetworkPolicyEgressPeer, baselineTo []v1alpha1.BaselineAdminNetworkPolicyEgressPeer, isIngress, isBanp bool) error {
×
877
        // 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
×
878

×
879
        var v4Addrs, v4Addr, v6Addrs, v6Addr []string
×
880
        var err error
×
881
        if isIngress {
×
882
                for _, anprpeer := range from {
×
883
                        if v4Addr, v6Addr, err = c.fetchIngressSelectedAddresses(&anprpeer); err != nil {
×
884
                                klog.Errorf("failed to fetch anp/banp ingress selected addresses, %v", err)
×
885
                                return err
×
886
                        }
×
887
                        v4Addrs = append(v4Addrs, v4Addr...)
×
888
                        v6Addrs = append(v6Addrs, v6Addr...)
×
889
                }
890
                klog.Infof("update anp/banp ingress rule %s, selected v4 address %v, v6 address %v", ruleName, v4Addrs, v6Addrs)
×
891

×
892
                gressAsV4Name, gressAsV6Name := getAnpAddressSetName(pgName, ruleName, index, true)
×
893
                if err = c.createAsForAnpRule(anpName, ruleName, "ingress", gressAsV4Name, v4Addrs, isBanp); err != nil {
×
894
                        klog.Error(err)
×
895
                        return err
×
896
                }
×
897
                if err = c.createAsForAnpRule(anpName, ruleName, "ingress", gressAsV6Name, v6Addrs, isBanp); err != nil {
×
898
                        klog.Error(err)
×
899
                        return err
×
900
                }
×
901
        } else {
×
902
                if to != nil {
×
903
                        for _, anprpeer := range to {
×
904
                                if v4Addr, v6Addr, err = c.fetchEgressSelectedAddresses(&anprpeer); err != nil {
×
905
                                        klog.Errorf("failed to fetch anp/banp egress selected addresses, %v", err)
×
906
                                        return err
×
907
                                }
×
908
                                v4Addrs = append(v4Addrs, v4Addr...)
×
909
                                v6Addrs = append(v6Addrs, v6Addr...)
×
910
                        }
911
                } else {
×
912
                        for _, anprpeer := range baselineTo {
×
913
                                if v4Addr, v6Addr, err = c.fetchBaselineEgressSelectedAddresses(&anprpeer); err != nil {
×
914
                                        klog.Errorf("failed to fetch baseline anp/banp egress selected addresses, %v", err)
×
915
                                        return err
×
916
                                }
×
917
                                v4Addrs = append(v4Addrs, v4Addr...)
×
918
                                v6Addrs = append(v6Addrs, v6Addr...)
×
919
                        }
920
                }
921
                klog.Infof("update anp/banp egress rule %s, selected v4 address %v, v6 address %v", ruleName, v4Addrs, v6Addrs)
×
922

×
923
                gressAsV4Name, gressAsV6Name := getAnpAddressSetName(pgName, ruleName, index, false)
×
924
                if err = c.createAsForAnpRule(anpName, ruleName, "egress", gressAsV4Name, v4Addrs, isBanp); err != nil {
×
925
                        klog.Error(err)
×
926
                        return err
×
927
                }
×
928
                if err = c.createAsForAnpRule(anpName, ruleName, "egress", gressAsV6Name, v6Addrs, isBanp); err != nil {
×
929
                        klog.Error(err)
×
930
                        return err
×
931
                }
×
932
        }
933

934
        return nil
×
935
}
936

937
func (c *Controller) updateAnpsByLabelsMatch(nsLabels, podLabels map[string]string) {
×
938
        anps, _ := c.anpsLister.List(labels.Everything())
×
939
        for _, anp := range anps {
×
940
                changed := &AdminNetworkPolicyChangedDelta{
×
941
                        key: anp.Name,
×
942
                }
×
943

×
944
                if isLabelsMatch(anp.Spec.Subject.Namespaces, anp.Spec.Subject.Pods, nsLabels, podLabels) {
×
945
                        klog.Infof("anp %s, labels matched for anp's subject, nsLabels %s, podLabels %s", anp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String())
×
946
                        changed.field = ChangedSubject
×
947
                        c.updateAnpQueue.Add(changed)
×
948
                }
×
949

950
                ingressRuleNames, egressRuleNames := isLabelsMatchAnpRulePeers(anp.Spec.Ingress, anp.Spec.Egress, nsLabels, podLabels)
×
951
                if !isRulesArrayEmpty(ingressRuleNames) {
×
952
                        klog.Infof("anp %s, labels matched for anp's ingress peer, nsLabels %s, podLabels %s", anp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String())
×
953
                        changed.ruleNames = ingressRuleNames
×
954
                        changed.field = ChangedIngressRule
×
955
                        c.updateAnpQueue.Add(changed)
×
956
                }
×
957

958
                if !isRulesArrayEmpty(egressRuleNames) {
×
959
                        klog.Infof("anp %s, labels matched for anp's egress peer, nsLabels %s, podLabels %s", anp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String())
×
960
                        changed.ruleNames = egressRuleNames
×
961
                        changed.field = ChangedEgressRule
×
962
                        c.updateAnpQueue.Add(changed)
×
963
                }
×
964
        }
965

966
        banps, _ := c.banpsLister.List(labels.Everything())
×
967
        for _, banp := range banps {
×
968
                changed := &AdminNetworkPolicyChangedDelta{
×
969
                        key: banp.Name,
×
970
                }
×
971

×
972
                if isLabelsMatch(banp.Spec.Subject.Namespaces, banp.Spec.Subject.Pods, nsLabels, podLabels) {
×
973
                        klog.Infof("banp %s, labels matched for banp's subject, nsLabels %s, podLabels %s", banp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String())
×
974
                        changed.field = ChangedSubject
×
975
                        c.updateBanpQueue.Add(changed)
×
976
                }
×
977

978
                ingressRuleNames, egressRuleNames := isLabelsMatchBanpRulePeers(banp.Spec.Ingress, banp.Spec.Egress, nsLabels, podLabels)
×
979
                if !isRulesArrayEmpty(ingressRuleNames) {
×
980
                        klog.Infof("banp %s, labels matched for banp's ingress peer, nsLabels %s, podLabels %s", banp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String())
×
981
                        changed.ruleNames = ingressRuleNames
×
982
                        changed.field = ChangedIngressRule
×
983
                        c.updateBanpQueue.Add(changed)
×
984
                }
×
985

986
                if !isRulesArrayEmpty(egressRuleNames) {
×
987
                        klog.Infof("banp %s, labels matched for banp's egress peer, nsLabels %s, podLabels %s", banp.Name, labels.Set(nsLabels).String(), labels.Set(podLabels).String())
×
988
                        changed.ruleNames = egressRuleNames
×
989
                        changed.field = ChangedEgressRule
×
990
                        c.updateBanpQueue.Add(changed)
×
991
                }
×
992
        }
993
}
994

995
func isLabelsMatch(namespaces *metav1.LabelSelector, pods *v1alpha1.NamespacedPod, nsLabels, podLabels map[string]string) bool {
1✔
996
        // Exactly one field of namespaces/pods must be set.
1✔
997
        if namespaces != nil {
2✔
998
                nsSelector, _ := metav1.LabelSelectorAsSelector(namespaces)
1✔
999
                klog.V(3).Infof("namespaces is not nil, nsSelector %s", nsSelector.String())
1✔
1000
                if nsSelector.Matches(labels.Set(nsLabels)) {
2✔
1001
                        return true
1✔
1002
                }
1✔
1003
        } else if pods != nil {
2✔
1004
                nsSelector, _ := metav1.LabelSelectorAsSelector(&pods.NamespaceSelector)
1✔
1005
                podSelector, _ := metav1.LabelSelectorAsSelector(&pods.PodSelector)
1✔
1006
                klog.V(3).Infof("pods is not nil, nsSelector %s, podSelector %s", nsSelector.String(), podSelector.String())
1✔
1007
                if nsSelector.Matches(labels.Set(nsLabels)) && podSelector.Matches(labels.Set(podLabels)) {
2✔
1008
                        return true
1✔
1009
                }
1✔
1010
        }
1011

1012
        return false
1✔
1013
}
1014

1015
func isLabelsMatchRulePeers(from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.AdminNetworkPolicyEgressPeer, nsLabels, podLabels map[string]string) bool {
×
1016
        return isLabelsMatchRulePeersCommon(from, to, nil, nsLabels, podLabels)
×
1017
}
×
1018

1019
func isLabelsMatchBaselineRulePeers(from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.BaselineAdminNetworkPolicyEgressPeer, nsLabels, podLabels map[string]string) bool {
×
1020
        return isLabelsMatchRulePeersCommon(from, nil, to, nsLabels, podLabels)
×
1021
}
×
1022

1023
func isLabelsMatchRulePeersCommon(from []v1alpha1.AdminNetworkPolicyIngressPeer, to []v1alpha1.AdminNetworkPolicyEgressPeer, baselineTo []v1alpha1.BaselineAdminNetworkPolicyEgressPeer, nsLabels, podLabels map[string]string) bool {
×
1024
        for _, ingressPeer := range from {
×
1025
                if isLabelsMatch(ingressPeer.Namespaces, ingressPeer.Pods, nsLabels, podLabels) {
×
1026
                        return true
×
1027
                }
×
1028
        }
1029

1030
        if to != nil {
×
1031
                for _, egressPeer := range to {
×
1032
                        if isLabelsMatch(egressPeer.Namespaces, egressPeer.Pods, nsLabels, podLabels) {
×
1033
                                return true
×
1034
                        }
×
1035
                }
1036
        } else {
×
1037
                for _, egressPeer := range baselineTo {
×
1038
                        if isLabelsMatch(egressPeer.Namespaces, egressPeer.Pods, nsLabels, podLabels) {
×
1039
                                return true
×
1040
                        }
×
1041
                }
1042
        }
1043

1044
        return false
×
1045
}
1046

1047
func isLabelsMatchAnpRulePeers(ingress []v1alpha1.AdminNetworkPolicyIngressRule, egress []v1alpha1.AdminNetworkPolicyEgressRule, nsLabels, podLabels map[string]string) ([util.AnpMaxRules]ChangedName, [util.AnpMaxRules]ChangedName) {
×
1048
        return isLabelsMatchAnpRulePeersCommon(ingress, egress, nil, nsLabels, podLabels)
×
1049
}
×
1050

1051
func isLabelsMatchBaselineAnpRulePeers(_ []v1alpha1.BaselineAdminNetworkPolicyIngressRule, egress []v1alpha1.BaselineAdminNetworkPolicyEgressRule, nsLabels, podLabels map[string]string) ([util.AnpMaxRules]ChangedName, [util.AnpMaxRules]ChangedName) {
×
1052
        return isLabelsMatchAnpRulePeersCommon(nil, nil, egress, nsLabels, podLabels)
×
1053
}
×
1054

1055
func isLabelsMatchAnpRulePeersCommon(ingress []v1alpha1.AdminNetworkPolicyIngressRule, egress []v1alpha1.AdminNetworkPolicyEgressRule, baselineEgress []v1alpha1.BaselineAdminNetworkPolicyEgressRule, nsLabels, podLabels map[string]string) ([util.AnpMaxRules]ChangedName, [util.AnpMaxRules]ChangedName) {
×
1056
        var changedIngressRuleNames, changedEgressRuleNames [util.AnpMaxRules]ChangedName
×
1057

×
1058
        for index, anpr := range ingress {
×
1059
                if isLabelsMatchRulePeers(anpr.From, []v1alpha1.AdminNetworkPolicyEgressPeer{}, nsLabels, podLabels) {
×
1060
                        changedIngressRuleNames[index].isMatch = true
×
1061
                        changedIngressRuleNames[index].curRuleName = anpr.Name
×
1062
                }
×
1063
        }
1064

1065
        if egress != nil {
×
1066
                for index, anpr := range egress {
×
1067
                        if isLabelsMatchRulePeers([]v1alpha1.AdminNetworkPolicyIngressPeer{}, anpr.To, nsLabels, podLabels) {
×
1068
                                changedEgressRuleNames[index].isMatch = true
×
1069
                                changedEgressRuleNames[index].curRuleName = anpr.Name
×
1070
                        }
×
1071
                }
1072
        } else {
×
1073
                for index, banpr := range baselineEgress {
×
1074
                        if isLabelsMatchBaselineRulePeers([]v1alpha1.AdminNetworkPolicyIngressPeer{}, banpr.To, nsLabels, podLabels) {
×
1075
                                changedEgressRuleNames[index].isMatch = true
×
1076
                                changedEgressRuleNames[index].curRuleName = banpr.Name
×
1077
                        }
×
1078
                }
1079
        }
1080

1081
        return changedIngressRuleNames, changedEgressRuleNames
×
1082
}
1083

1084
func isLabelsMatchBanpRulePeers(ingress []v1alpha1.BaselineAdminNetworkPolicyIngressRule, egress []v1alpha1.BaselineAdminNetworkPolicyEgressRule, nsLabels, podLabels map[string]string) ([util.AnpMaxRules]ChangedName, [util.AnpMaxRules]ChangedName) {
×
1085
        return isLabelsMatchBaselineAnpRulePeers(ingress, egress, nsLabels, podLabels)
×
1086
}
×
1087

1088
func getAnpName(name string) string {
1✔
1089
        anpName := name
1✔
1090
        nameArray := []rune(name)
1✔
1091
        if !unicode.IsLetter(nameArray[0]) {
2✔
1092
                anpName = "anp" + name
1✔
1093
        }
1✔
1094
        return anpName
1✔
1095
}
1096

1097
func getAnpAddressSetName(pgName, ruleName string, index int, isIngress bool) (string, string) {
1✔
1098
        var asV4Name, asV6Name string
1✔
1099
        if isIngress {
2✔
1100
                // In case ruleName is omitted, add direction and index to distinguish address-set
1✔
1101
                asV4Name = strings.ReplaceAll(fmt.Sprintf("%s.ingress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv4), "-", ".")
1✔
1102
                asV6Name = strings.ReplaceAll(fmt.Sprintf("%s.ingress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv6), "-", ".")
1✔
1103
        } else {
2✔
1104
                asV4Name = strings.ReplaceAll(fmt.Sprintf("%s.egress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv4), "-", ".")
1✔
1105
                asV6Name = strings.ReplaceAll(fmt.Sprintf("%s.egress.%d.%s.%s", pgName, index, ruleName, kubeovnv1.ProtocolIPv6), "-", ".")
1✔
1106
        }
1✔
1107

1108
        return asV4Name, asV6Name
1✔
1109
}
1110

1111
func anpACLAction(action v1alpha1.AdminNetworkPolicyRuleAction) ovnnb.ACLAction {
1✔
1112
        switch action {
1✔
1113
        case v1alpha1.AdminNetworkPolicyRuleActionAllow:
1✔
1114
                return ovnnb.ACLActionAllowRelated
1✔
1115
        case v1alpha1.AdminNetworkPolicyRuleActionDeny:
1✔
1116
                return ovnnb.ACLActionDrop
1✔
1117
        case v1alpha1.AdminNetworkPolicyRuleActionPass:
1✔
1118
                return ovnnb.ACLActionPass
1✔
1119
        }
1120
        return ovnnb.ACLActionDrop
1✔
1121
}
1122

1123
func isRulesArrayEmpty(ruleNames [util.AnpMaxRules]ChangedName) bool {
1✔
1124
        for _, ruleName := range ruleNames {
2✔
1125
                // The ruleName can be omitted default
1✔
1126
                if ruleName.curRuleName != "" || ruleName.isMatch {
2✔
1127
                        return false
1✔
1128
                }
1✔
1129
        }
1130
        return true
1✔
1131
}
1132

1133
func (c *Controller) fetchNodesAddrs(nodeSelector labels.Selector) ([]string, []string, error) {
×
1134
        nodes, err := c.nodesLister.List(nodeSelector)
×
1135
        if err != nil {
×
1136
                klog.Errorf("failed to list nodes: %v", err)
×
1137
                return nil, nil, err
×
1138
        }
×
1139
        v4Addresses := make([]string, 0, len(nodes))
×
1140
        v6Addresses := make([]string, 0, len(nodes))
×
1141

×
1142
        klog.V(3).Infof("fetch nodes addresses, selector is %s", nodeSelector.String())
×
1143
        for _, node := range nodes {
×
1144
                nodeIPv4, nodeIPv6 := util.GetNodeInternalIP(*node)
×
1145
                if nodeIPv4 != "" {
×
1146
                        v4Addresses = append(v4Addresses, nodeIPv4)
×
1147
                }
×
1148
                if nodeIPv6 != "" {
×
1149
                        v6Addresses = append(v6Addresses, nodeIPv6)
×
1150
                }
×
1151
        }
1152

1153
        return v4Addresses, v6Addresses, nil
×
1154
}
1155

1156
func fetchCIDRAddrs(networks []v1alpha1.CIDR) ([]string, []string) {
1✔
1157
        var v4Addresses, v6Addresses []string
1✔
1158

1✔
1159
        for _, network := range networks {
2✔
1160
                if _, _, err := net.ParseCIDR(string(network)); err != nil {
2✔
1161
                        klog.Errorf("invalid cidr %s", string(network))
1✔
1162
                        continue
1✔
1163
                }
1164
                switch util.CheckProtocol(string(network)) {
1✔
1165
                case kubeovnv1.ProtocolIPv4:
1✔
1166
                        v4Addresses = append(v4Addresses, string(network))
1✔
1167
                case kubeovnv1.ProtocolIPv6:
1✔
1168
                        v6Addresses = append(v6Addresses, string(network))
1✔
1169
                }
1170
        }
1171

1172
        return v4Addresses, v6Addresses
1✔
1173
}
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