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

kubeovn / kube-ovn / 12545917939

30 Dec 2024 11:29AM UTC coverage: 22.079% (-0.01%) from 22.093%
12545917939

Pull #4777

github

web-flow
Merge branch 'master' into fix-ipampools-ns
Pull Request #4777: Support multiple IPPools in the namespace

0 of 30 new or added lines in 2 files covered. (0.0%)

3 existing lines in 2 files now uncovered.

10160 of 46016 relevant lines covered (22.08%)

0.26 hits per line

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

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

3
import (
4
        "reflect"
5
        "slices"
6
        "strings"
7

8
        "github.com/scylladb/go-set/strset"
9
        v1 "k8s.io/api/core/v1"
10
        "k8s.io/apimachinery/pkg/api/errors"
11
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
        "k8s.io/apimachinery/pkg/labels"
13
        "k8s.io/client-go/tools/cache"
14
        "k8s.io/klog/v2"
15

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

19
func (c *Controller) enqueueAddNamespace(obj interface{}) {
×
20
        if c.config.EnableNP {
×
21
                for _, np := range c.namespaceMatchNetworkPolicies(obj.(*v1.Namespace)) {
×
22
                        c.updateNpQueue.Add(np)
×
23
                }
×
24
        }
25

26
        key := cache.MetaObjectToName(obj.(*v1.Namespace)).String()
×
27
        c.addNamespaceQueue.Add(key)
×
28
}
29

30
func (c *Controller) enqueueDeleteNamespace(obj interface{}) {
×
31
        if c.config.EnableNP {
×
32
                for _, np := range c.namespaceMatchNetworkPolicies(obj.(*v1.Namespace)) {
×
33
                        c.updateNpQueue.Add(np)
×
34
                }
×
35
        }
36
        if c.config.EnableANP {
×
37
                c.updateAnpsByLabelsMatch(obj.(*v1.Namespace).Labels, nil)
×
38
        }
×
39
}
40

41
func (c *Controller) enqueueUpdateNamespace(oldObj, newObj interface{}) {
×
42
        oldNs := oldObj.(*v1.Namespace)
×
43
        newNs := newObj.(*v1.Namespace)
×
44
        if oldNs.ResourceVersion == newNs.ResourceVersion {
×
45
                return
×
46
        }
×
47

48
        if !reflect.DeepEqual(oldNs.Labels, newNs.Labels) {
×
49
                if c.config.EnableNP {
×
50
                        oldNp := c.namespaceMatchNetworkPolicies(oldNs)
×
51
                        newNp := c.namespaceMatchNetworkPolicies(newNs)
×
52
                        for _, np := range util.DiffStringSlice(oldNp, newNp) {
×
53
                                c.updateNpQueue.Add(np)
×
54
                        }
×
55
                }
56

57
                if c.config.EnableANP {
×
58
                        c.updateAnpsByLabelsMatch(newObj.(*v1.Namespace).Labels, nil)
×
59
                }
×
60

61
                expectSubnets, err := c.getNsExpectSubnets(newNs)
×
62
                if err != nil {
×
63
                        klog.Errorf("failed to list expected subnets for namespace %s, %v", newNs.Name, err)
×
64
                        return
×
65
                }
×
66

67
                expectSubnetsSet := strset.New(expectSubnets...)
×
68
                existSubnetsSet := strset.New(strings.Split(newNs.Annotations[util.LogicalSwitchAnnotation], ",")...)
×
69
                if !expectSubnetsSet.IsEqual(existSubnetsSet) {
×
70
                        c.addNamespaceQueue.Add(newNs.Name)
×
71
                }
×
72
        }
73

74
        // in case annotations are removed by other controllers
75
        if newNs.Annotations == nil || newNs.Annotations[util.LogicalSwitchAnnotation] == "" {
×
76
                klog.Warningf("no logical switch annotation for ns %s", newNs.Name)
×
77
                c.addNamespaceQueue.Add(newNs.Name)
×
78
        }
×
79
}
80

81
func (c *Controller) handleAddNamespace(key string) error {
×
82
        c.nsKeyMutex.LockKey(key)
×
83
        defer func() { _ = c.nsKeyMutex.UnlockKey(key) }()
×
84
        klog.Infof("handle add/update namespace %s", key)
×
85

×
86
        cachedNs, err := c.namespacesLister.Get(key)
×
87
        if err != nil {
×
88
                if errors.IsNotFound(err) {
×
89
                        return nil
×
90
                }
×
91
                klog.Error(err)
×
92
                return err
×
93
        }
94
        namespace := cachedNs.DeepCopy()
×
95

×
NEW
96
        var ls string
×
NEW
97
        var lss, cidrs, excludeIps, ipPoolsAnnotation []string
×
98
        subnets, err := c.subnetsLister.List(labels.Everything())
×
99
        if err != nil {
×
100
                klog.Errorf("failed to list subnets %v", err)
×
101
                return err
×
102
        }
×
NEW
103
        ipPoolList, err := c.ippoolLister.List(labels.Everything())
×
104
        if err != nil {
×
105
                klog.Errorf("failed to list ippools: %v", err)
×
106
                return err
×
107
        }
×
108

109
        // check if subnet bind ns
110
        for _, s := range subnets {
×
111
                for _, ns := range s.Spec.Namespaces {
×
112
                        if ns == key {
×
113
                                lss = append(lss, s.Name)
×
114
                                cidrs = append(cidrs, s.Spec.CIDRBlock)
×
115
                                excludeIps = append(excludeIps, strings.Join(s.Spec.ExcludeIps, ","))
×
116
                                break
×
117
                        }
118
                }
119

120
                // bind subnet with namespaceLabelSeletcor which select the namespace
121
                for _, nsSelector := range s.Spec.NamespaceSelectors {
×
122
                        matchSelector, err := metav1.LabelSelectorAsSelector(&nsSelector)
×
123
                        if err != nil {
×
124
                                klog.Errorf("failed to convert label selector, %v", err)
×
125
                                return err
×
126
                        }
×
127

128
                        if matchSelector.Matches(labels.Set(namespace.Labels)) {
×
129
                                if slices.Contains(lss, s.Name) {
×
130
                                        break
×
131
                                }
132
                                lss = append(lss, s.Name)
×
133
                                cidrs = append(cidrs, s.Spec.CIDRBlock)
×
134
                                excludeIps = append(excludeIps, strings.Join(s.Spec.ExcludeIps, ","))
×
135
                                break
×
136
                        }
137
                }
138

139
                // check if subnet is in custom vpc with configured defaultSubnet, then annotate the namespace with this subnet
140
                if s.Spec.Vpc != "" && s.Spec.Vpc != c.config.ClusterRouter {
×
141
                        vpc, err := c.vpcsLister.Get(s.Spec.Vpc)
×
142
                        if err != nil {
×
143
                                klog.Errorf("failed to get custom vpc %v", err)
×
144
                                return err
×
145
                        }
×
146
                        if s.Name == vpc.Spec.DefaultSubnet {
×
147
                                if slices.Contains(vpc.Spec.Namespaces, key) && key != metav1.NamespaceSystem {
×
148
                                        lss = append([]string{s.Name}, lss...)
×
149
                                }
×
150
                        }
151
                }
152
        }
153

NEW
154
        for _, ipPool := range ipPoolList {
×
NEW
155
                if slices.Contains(ipPool.Spec.Namespaces, key) {
×
NEW
156
                        ipPoolsAnnotation = append(ipPoolsAnnotation, ipPool.Name)
×
UNCOV
157
                }
×
158
        }
159

160
        if lss == nil {
×
161
                // If NS does not belong to any custom VPC, then this NS belongs to the default VPC
×
162
                vpc, err := c.vpcsLister.Get(c.config.ClusterRouter)
×
163
                if err != nil {
×
164
                        klog.Errorf("failed to get default vpc %v", err)
×
165
                        return err
×
166
                }
×
167
                vpcs, err := c.vpcsLister.List(labels.Everything())
×
168
                if err != nil {
×
169
                        klog.Errorf("failed to list vpc %v", err)
×
170
                        return err
×
171
                }
×
172
                for _, v := range vpcs {
×
173
                        if slices.Contains(v.Spec.Namespaces, key) {
×
174
                                vpc = v
×
175
                                break
×
176
                        }
177
                }
178

179
                if vpc.Status.DefaultLogicalSwitch != "" {
×
180
                        ls = vpc.Status.DefaultLogicalSwitch
×
181
                } else {
×
182
                        ls = c.config.DefaultLogicalSwitch
×
183
                }
×
184
                subnet, err := c.subnetsLister.Get(ls)
×
185
                if err != nil {
×
186
                        klog.Errorf("failed to get default subnet %v", err)
×
187
                        return err
×
188
                }
×
189
                lss = append(lss, subnet.Name)
×
190
                cidrs = append(cidrs, subnet.Spec.CIDRBlock)
×
191
                excludeIps = append(excludeIps, strings.Join(subnet.Spec.ExcludeIps, ","))
×
192
        }
193

194
        if namespace.Annotations[util.LogicalSwitchAnnotation] == strings.Join(lss, ",") &&
×
195
                namespace.Annotations[util.CidrAnnotation] == strings.Join(cidrs, ";") &&
×
196
                namespace.Annotations[util.ExcludeIpsAnnotation] == strings.Join(excludeIps, ";") &&
×
NEW
197
                namespace.Annotations[util.IPPoolAnnotation] == strings.Join(ipPoolsAnnotation, ",") {
×
198
                return nil
×
199
        }
×
200

201
        patch := util.KVPatch{
×
202
                util.LogicalSwitchAnnotation: strings.Join(lss, ","),
×
203
                util.CidrAnnotation:          strings.Join(cidrs, ";"),
×
204
                util.ExcludeIpsAnnotation:    strings.Join(excludeIps, ";"),
×
205
        }
×
NEW
206

×
NEW
207
        if len(ipPoolsAnnotation) == 0 {
×
208
                patch[util.IPPoolAnnotation] = nil
×
209
        } else {
×
NEW
210
                patch[util.IPPoolAnnotation] = strings.Join(ipPoolsAnnotation, ",")
×
211
        }
×
212

213
        if err = util.PatchAnnotations(c.config.KubeClient.CoreV1().Namespaces(), key, patch); err != nil {
×
214
                klog.Errorf("patch namespace %s failed %v", key, err)
×
215
        }
×
216
        return err
×
217
}
218

219
func (c *Controller) getNsExpectSubnets(newNs *v1.Namespace) ([]string, error) {
×
220
        var expectSubnets []string
×
221

×
222
        subnets, err := c.subnetsLister.List(labels.Everything())
×
223
        if err != nil {
×
224
                klog.Errorf("failed to list subnets %v", err)
×
225
                return expectSubnets, err
×
226
        }
×
227
        for _, subnet := range subnets {
×
228
                // ns labels match subnet's selector
×
229
                for _, nsSelector := range subnet.Spec.NamespaceSelectors {
×
230
                        matchSelector, err := metav1.LabelSelectorAsSelector(&nsSelector)
×
231
                        if err != nil {
×
232
                                klog.Errorf("failed to convert label selector, %v", err)
×
233
                                return expectSubnets, err
×
234
                        }
×
235

236
                        if matchSelector.Matches(labels.Set(newNs.Labels)) {
×
237
                                expectSubnets = append(expectSubnets, subnet.Name)
×
238
                                break
×
239
                        }
240
                }
241

242
                // ns included in subnet's namespaces
243
                if slices.Contains(subnet.Spec.Namespaces, newNs.Name) && !slices.Contains(expectSubnets, subnet.Name) {
×
244
                        expectSubnets = append(expectSubnets, subnet.Name)
×
245
                }
×
246
        }
247

248
        return expectSubnets, nil
×
249
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc