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

kubeovn / kube-ovn / 19498592422

19 Nov 2025 10:45AM UTC coverage: 22.278% (+0.4%) from 21.909%
19498592422

Pull #5920

github

zbb88888
fix e2e

Signed-off-by: zbb88888 <jmdxjsjgcxy@gmail.com>
Pull Request #5920: IPPool sync to address set

274 of 415 new or added lines in 4 files covered. (66.02%)

3 existing lines in 2 files now uncovered.

11409 of 51212 relevant lines covered (22.28%)

0.26 hits per line

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

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

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

9
        corev1 "k8s.io/api/core/v1"
10
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
11
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
        "k8s.io/apimachinery/pkg/labels"
13
        "k8s.io/apimachinery/pkg/types"
14
        "k8s.io/client-go/tools/cache"
15
        "k8s.io/klog/v2"
16
        "sigs.k8s.io/controller-runtime/pkg/client"
17
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
18

19
        kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
20
        "github.com/kubeovn/kube-ovn/pkg/util"
21
)
22

23
func (c *Controller) enqueueAddIPPool(obj any) {
×
24
        key := cache.MetaObjectToName(obj.(*kubeovnv1.IPPool)).String()
×
25
        klog.V(3).Infof("enqueue add ippool %s", key)
×
26
        c.addOrUpdateIPPoolQueue.Add(key)
×
27
}
×
28

29
func (c *Controller) enqueueDeleteIPPool(obj any) {
×
30
        var ippool *kubeovnv1.IPPool
×
31
        switch t := obj.(type) {
×
32
        case *kubeovnv1.IPPool:
×
33
                ippool = t
×
34
        case cache.DeletedFinalStateUnknown:
×
35
                i, ok := t.Obj.(*kubeovnv1.IPPool)
×
36
                if !ok {
×
37
                        klog.Warningf("unexpected object type: %T", t.Obj)
×
38
                        return
×
39
                }
×
40
                ippool = i
×
41
        default:
×
42
                klog.Warningf("unexpected type: %T", obj)
×
43
                return
×
44
        }
45

46
        klog.V(3).Infof("enqueue delete ippool %s", cache.MetaObjectToName(ippool).String())
×
47
        c.deleteIPPoolQueue.Add(ippool)
×
48
}
49

50
func (c *Controller) enqueueUpdateIPPool(oldObj, newObj any) {
×
51
        oldIPPool := oldObj.(*kubeovnv1.IPPool)
×
52
        newIPPool := newObj.(*kubeovnv1.IPPool)
×
NEW
53
        if !newIPPool.DeletionTimestamp.IsZero() {
×
NEW
54
                klog.V(3).Infof("enqueue delete ippool %s due to deletion timestamp", cache.MetaObjectToName(newIPPool).String())
×
NEW
55
                c.deleteIPPoolQueue.Add(newIPPool.DeepCopy())
×
NEW
56
                return
×
NEW
57
        }
×
58
        if !slices.Equal(oldIPPool.Spec.Namespaces, newIPPool.Spec.Namespaces) ||
×
NEW
59
                !slices.Equal(oldIPPool.Spec.IPs, newIPPool.Spec.IPs) ||
×
NEW
60
                oldIPPool.Spec.EnableAddressSet != newIPPool.Spec.EnableAddressSet {
×
61
                key := cache.MetaObjectToName(newIPPool).String()
×
62
                klog.V(3).Infof("enqueue update ippool %s", key)
×
63
                c.addOrUpdateIPPoolQueue.Add(key)
×
64
        }
×
65
}
66

67
func (c *Controller) handleAddOrUpdateIPPool(key string) error {
×
68
        c.ippoolKeyMutex.LockKey(key)
×
69
        defer func() { _ = c.ippoolKeyMutex.UnlockKey(key) }()
×
70

71
        cachedIPPool, err := c.ippoolLister.Get(key)
×
72
        if err != nil {
×
73
                if k8serrors.IsNotFound(err) {
×
74
                        return nil
×
75
                }
×
76
                klog.Error(err)
×
77
                return err
×
78
        }
79
        klog.Infof("handle add/update ippool %s", cachedIPPool.Name)
×
80

×
81
        ippool := cachedIPPool.DeepCopy()
×
NEW
82
        if err = c.handleAddIPPoolFinalizer(ippool); err != nil {
×
NEW
83
                klog.Errorf("failed to add finalizer for ippool %s: %v", ippool.Name, err)
×
NEW
84
                return err
×
NEW
85
        }
×
NEW
86
        if !ippool.DeletionTimestamp.IsZero() {
×
NEW
87
                klog.Infof("ippool %s is being deleted, skip add/update handling", ippool.Name)
×
NEW
88
                return nil
×
NEW
89
        }
×
90
        ippool.Status.EnsureStandardConditions()
×
NEW
91
        if err = c.reconcileIPPoolAddressSet(ippool); err != nil {
×
NEW
92
                klog.Errorf("failed to reconcile address set for ippool %s: %v", ippool.Name, err)
×
NEW
93
                if patchErr := c.patchIPPoolStatusCondition(ippool, "ReconcileAddressSetFailed", err.Error()); patchErr != nil {
×
NEW
94
                        klog.Error(patchErr)
×
NEW
95
                }
×
NEW
96
                return err
×
97
        }
98
        if err = c.ipam.AddOrUpdateIPPool(ippool.Spec.Subnet, ippool.Name, ippool.Spec.IPs); err != nil {
×
99
                klog.Errorf("failed to add/update ippool %s with IPs %v in subnet %s: %v", ippool.Name, ippool.Spec.IPs, ippool.Spec.Subnet, err)
×
100
                if patchErr := c.patchIPPoolStatusCondition(ippool, "UpdateIPAMFailed", err.Error()); patchErr != nil {
×
101
                        klog.Error(patchErr)
×
102
                }
×
103
                return err
×
104
        }
105

NEW
106
        c.updateIPPoolStatistics(ippool)
×
107

×
108
        if err = c.patchIPPoolStatusCondition(ippool, "UpdateIPAMSucceeded", ""); err != nil {
×
109
                klog.Error(err)
×
110
                return err
×
111
        }
×
112

113
        for _, ns := range ippool.Spec.Namespaces {
×
114
                c.addNamespaceQueue.Add(ns)
×
115
        }
×
116

117
        return nil
×
118
}
119

120
func (c *Controller) handleDeleteIPPool(ippool *kubeovnv1.IPPool) error {
×
121
        c.ippoolKeyMutex.LockKey(ippool.Name)
×
122
        defer func() { _ = c.ippoolKeyMutex.UnlockKey(ippool.Name) }()
×
123

124
        klog.Infof("handle delete ippool %s", ippool.Name)
×
125
        c.ipam.RemoveIPPool(ippool.Spec.Subnet, ippool.Name)
×
NEW
126
        if err := c.OVNNbClient.DeleteAddressSet(util.IPPoolAddressSetName(ippool.Name)); err != nil {
×
NEW
127
                klog.Errorf("failed to delete address set for ippool %s: %v", ippool.Name, err)
×
NEW
128
                return err
×
NEW
129
        }
×
130

131
        namespaces, err := c.namespacesLister.List(labels.Everything())
×
132
        if err != nil {
×
133
                klog.Errorf("failed to list namespaces: %v", err)
×
134
                return err
×
135
        }
×
136

137
        for _, ns := range namespaces {
×
138
                if ns.Annotations[util.IPPoolAnnotation] == ippool.Name {
×
139
                        c.enqueueAddNamespace(ns)
×
140
                }
×
141
        }
142

NEW
143
        if err := c.handleDelIPPoolFinalizer(ippool); err != nil {
×
NEW
144
                klog.Errorf("failed to remove finalizer for ippool %s: %v", ippool.Name, err)
×
NEW
145
                return err
×
NEW
146
        }
×
147

UNCOV
148
        return nil
×
149
}
150

151
func (c *Controller) handleUpdateIPPoolStatus(key string) error {
×
152
        c.ippoolKeyMutex.LockKey(key)
×
153
        defer func() { _ = c.ippoolKeyMutex.UnlockKey(key) }()
×
154

155
        cachedIPPool, err := c.ippoolLister.Get(key)
×
156
        if err != nil {
×
157
                if k8serrors.IsNotFound(err) {
×
158
                        return nil
×
159
                }
×
160
                klog.Error(err)
×
161
                return err
×
162
        }
163

164
        ippool := cachedIPPool.DeepCopy()
×
NEW
165
        c.updateIPPoolStatistics(ippool)
×
166
        if reflect.DeepEqual(ippool.Status, cachedIPPool.Status) {
×
167
                return nil
×
168
        }
×
169

170
        return c.patchIPPoolStatus(ippool)
×
171
}
172

173
func (c Controller) patchIPPoolStatusCondition(ippool *kubeovnv1.IPPool, reason, errMsg string) error {
×
174
        if errMsg != "" {
×
175
                ippool.Status.SetError(reason, errMsg)
×
176
                ippool.Status.NotReady(reason, errMsg)
×
177
                c.recorder.Eventf(ippool, corev1.EventTypeWarning, reason, errMsg)
×
178
        } else {
×
179
                ippool.Status.Ready(reason, "")
×
180
        }
×
181

182
        return c.patchIPPoolStatus(ippool)
×
183
}
184

185
func (c Controller) patchIPPoolStatus(ippool *kubeovnv1.IPPool) error {
×
186
        bytes, err := ippool.Status.Bytes()
×
187
        if err != nil {
×
188
                klog.Errorf("failed to generate json representation for status of ippool %s: %v", ippool.Name, err)
×
189
                return err
×
190
        }
×
191
        if _, err = c.config.KubeOvnClient.KubeovnV1().IPPools().Patch(context.Background(), ippool.Name, types.MergePatchType, bytes, metav1.PatchOptions{}, "status"); err != nil {
×
192
                klog.Errorf("failed to patch status of ippool %s: %v", ippool.Name, err)
×
193
                return err
×
194
        }
×
195

196
        return nil
×
197
}
198

NEW
199
func (c *Controller) syncIPPoolFinalizer(cl client.Client) error {
×
NEW
200
        ippools := &kubeovnv1.IPPoolList{}
×
NEW
201
        return migrateFinalizers(cl, ippools, func(i int) (client.Object, client.Object) {
×
NEW
202
                if i < 0 || i >= len(ippools.Items) {
×
NEW
203
                        return nil, nil
×
NEW
204
                }
×
NEW
205
                return ippools.Items[i].DeepCopy(), ippools.Items[i].DeepCopy()
×
206
        })
207
}
208

NEW
209
func (c *Controller) handleAddIPPoolFinalizer(ippool *kubeovnv1.IPPool) error {
×
NEW
210
        if ippool == nil || !ippool.DeletionTimestamp.IsZero() {
×
NEW
211
                return nil
×
NEW
212
        }
×
NEW
213
        if controllerutil.ContainsFinalizer(ippool, util.KubeOVNControllerFinalizer) {
×
NEW
214
                return nil
×
NEW
215
        }
×
216

NEW
217
        newIPPool := ippool.DeepCopy()
×
NEW
218
        controllerutil.AddFinalizer(newIPPool, util.KubeOVNControllerFinalizer)
×
NEW
219
        patch, err := util.GenerateMergePatchPayload(ippool, newIPPool)
×
NEW
220
        if err != nil {
×
NEW
221
                klog.Errorf("failed to generate patch payload for ippool %s: %v", ippool.Name, err)
×
NEW
222
                return err
×
NEW
223
        }
×
NEW
224
        if _, err = c.config.KubeOvnClient.KubeovnV1().IPPools().Patch(context.Background(), ippool.Name,
×
NEW
225
                types.MergePatchType, patch, metav1.PatchOptions{}, ""); err != nil {
×
NEW
226
                if k8serrors.IsNotFound(err) {
×
NEW
227
                        return nil
×
NEW
228
                }
×
NEW
229
                klog.Errorf("failed to add finalizer for ippool %s: %v", ippool.Name, err)
×
NEW
230
                return err
×
231
        }
NEW
232
        return nil
×
233
}
234

NEW
235
func (c *Controller) handleDelIPPoolFinalizer(ippool *kubeovnv1.IPPool) error {
×
NEW
236
        if ippool == nil || len(ippool.GetFinalizers()) == 0 {
×
NEW
237
                return nil
×
NEW
238
        }
×
239

NEW
240
        newIPPool := ippool.DeepCopy()
×
NEW
241
        controllerutil.RemoveFinalizer(newIPPool, util.DepreciatedFinalizerName)
×
NEW
242
        controllerutil.RemoveFinalizer(newIPPool, util.KubeOVNControllerFinalizer)
×
NEW
243
        patch, err := util.GenerateMergePatchPayload(ippool, newIPPool)
×
NEW
244
        if err != nil {
×
NEW
245
                klog.Errorf("failed to generate patch payload for ippool %s: %v", ippool.Name, err)
×
NEW
246
                return err
×
NEW
247
        }
×
NEW
248
        if _, err = c.config.KubeOvnClient.KubeovnV1().IPPools().Patch(context.Background(), ippool.Name,
×
NEW
249
                types.MergePatchType, patch, metav1.PatchOptions{}, ""); err != nil {
×
NEW
250
                if k8serrors.IsNotFound(err) {
×
NEW
251
                        return nil
×
NEW
252
                }
×
NEW
253
                klog.Errorf("failed to remove finalizer from ippool %s: %v", ippool.Name, err)
×
NEW
254
                return err
×
255
        }
NEW
256
        return nil
×
257
}
258

NEW
259
func (c *Controller) updateIPPoolStatistics(ippool *kubeovnv1.IPPool) {
×
NEW
260
        v4a, v4u, v6a, v6u, v4as, v4us, v6as, v6us := c.ipam.IPPoolStatistics(ippool.Spec.Subnet, ippool.Name)
×
NEW
261
        ippool.Status.V4AvailableIPs = v4a
×
NEW
262
        ippool.Status.V4UsingIPs = v4u
×
NEW
263
        ippool.Status.V6AvailableIPs = v6a
×
NEW
264
        ippool.Status.V6UsingIPs = v6u
×
NEW
265
        ippool.Status.V4AvailableIPRange = v4as
×
NEW
266
        ippool.Status.V4UsingIPRange = v4us
×
NEW
267
        ippool.Status.V6AvailableIPRange = v6as
×
NEW
268
        ippool.Status.V6UsingIPRange = v6us
×
NEW
269
}
×
270

NEW
271
func (c *Controller) reconcileIPPoolAddressSet(ippool *kubeovnv1.IPPool) error {
×
NEW
272
        asName := util.IPPoolAddressSetName(ippool.Name)
×
NEW
273

×
NEW
274
        if !ippool.Spec.EnableAddressSet {
×
NEW
275
                if err := c.OVNNbClient.DeleteAddressSet(asName); err != nil {
×
NEW
276
                        err = fmt.Errorf("failed to delete address set %s: %w", asName, err)
×
NEW
277
                        klog.Error(err)
×
NEW
278
                        return err
×
NEW
279
                }
×
NEW
280
                return nil
×
281
        }
282

NEW
283
        addresses, err := util.ExpandIPPoolAddressesForOVN(ippool.Spec.IPs)
×
NEW
284
        if err != nil {
×
NEW
285
                err = fmt.Errorf("failed to build address set entries for ippool %s: %w", ippool.Name, err)
×
NEW
286
                klog.Error(err)
×
NEW
287
                return err
×
NEW
288
        }
×
289

NEW
290
        if err := c.OVNNbClient.CreateAddressSet(asName, map[string]string{ippoolKey: ippool.Name}); err != nil {
×
NEW
291
                err = fmt.Errorf("failed to create address set for ippool %s: %w", ippool.Name, err)
×
NEW
292
                klog.Error(err)
×
NEW
293
                return err
×
NEW
294
        }
×
295

NEW
296
        if err := c.OVNNbClient.AddressSetUpdateAddress(asName, addresses...); err != nil {
×
NEW
297
                err = fmt.Errorf("failed to update address set for ippool %s: %w", ippool.Name, err)
×
NEW
298
                klog.Error(err)
×
NEW
299
                return err
×
NEW
300
        }
×
301

NEW
302
        return nil
×
303
}
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