@@ -9,11 +9,11 @@ import (
9
9
"github.com/ovn-org/libovsdb/ovsdb"
10
10
k8serrors "k8s.io/apimachinery/pkg/api/errors"
11
11
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
+ "k8s.io/apimachinery/pkg/labels"
12
13
"k8s.io/apimachinery/pkg/types"
13
14
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
14
15
"k8s.io/client-go/tools/cache"
15
16
"k8s.io/klog/v2"
16
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
17
17
18
18
kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
19
19
"github.com/kubeovn/kube-ovn/pkg/util"
@@ -41,14 +41,9 @@ func (c *Controller) enqueueUpdateOvnDnatRule(old, new interface{}) {
41
41
oldDnat := old .(* kubeovnv1.OvnDnatRule )
42
42
newDnat := new .(* kubeovnv1.OvnDnatRule )
43
43
if ! newDnat .DeletionTimestamp .IsZero () {
44
- if len (newDnat .Finalizers ) == 0 {
45
- // avoid delete dnat twice
46
- return
47
- } else {
48
- klog .V (3 ).Infof ("enqueue del ovn dnat %s" , key )
49
- c .delOvnDnatRuleQueue .Add (key )
50
- return
51
- }
44
+ klog .Infof ("enqueue del ovn dnat %s" , key )
45
+ c .delOvnDnatRuleQueue .Add (key )
46
+ return
52
47
}
53
48
54
49
if oldDnat .Spec .OvnEip != newDnat .Spec .OvnEip {
@@ -60,7 +55,7 @@ func (c *Controller) enqueueUpdateOvnDnatRule(old, new interface{}) {
60
55
oldDnat .Spec .IpName != newDnat .Spec .IpName ||
61
56
oldDnat .Spec .InternalPort != newDnat .Spec .InternalPort ||
62
57
oldDnat .Spec .ExternalPort != newDnat .Spec .ExternalPort {
63
- klog .V ( 3 ). Infof ("enqueue update dnat %s" , key )
58
+ klog .Infof ("enqueue update dnat %s" , key )
64
59
c .updateOvnDnatRuleQueue .Add (key )
65
60
}
66
61
}
@@ -181,6 +176,27 @@ func (c *Controller) processNextDeleteOvnDnatRuleWorkItem() bool {
181
176
return true
182
177
}
183
178
179
+ func (c * Controller ) isOvnDnatDuplicated (eipName , dnatName , externalPort string ) (bool , error ) {
180
+ // check if eip:external port already used
181
+ dnats , err := c .ovnDnatRulesLister .List (labels .SelectorFromSet (labels.Set {
182
+ util .VpcDnatEPortLabel : externalPort ,
183
+ }))
184
+ if err != nil {
185
+ if ! k8serrors .IsNotFound (err ) {
186
+ return false , err
187
+ }
188
+ }
189
+ if len (dnats ) != 0 {
190
+ for _ , d := range dnats {
191
+ if d .Name != dnatName && d .Spec .OvnEip == eipName {
192
+ err = fmt .Errorf ("failed to create dnat %s, duplicate, same eip %s, same external port '%s' is using by dnat %s" , dnatName , eipName , externalPort , d .Name )
193
+ return true , err
194
+ }
195
+ }
196
+ }
197
+ return false , nil
198
+ }
199
+
184
200
func (c * Controller ) handleAddOvnDnatRule (key string ) error {
185
201
cachedDnat , err := c .ovnDnatRulesLister .Get (key )
186
202
if err != nil {
@@ -230,6 +246,16 @@ func (c *Controller) handleAddOvnDnatRule(key string) error {
230
246
return err
231
247
}
232
248
249
+ if cachedEip .Status .Type != "" && cachedEip .Status .Type != util .NatUsingEip {
250
+ err = fmt .Errorf ("ovn eip %s type is not %s, can not use" , cachedEip .Name , util .NatUsingEip )
251
+ return err
252
+ }
253
+
254
+ if _ , err := c .isOvnDnatDuplicated (eipName , key , cachedDnat .Spec .ExternalPort ); err != nil {
255
+ klog .Error ("failed to create dnat %s, %v" , cachedDnat .Name , err )
256
+ return err
257
+ }
258
+
233
259
subnet , err := c .subnetsLister .Get (subnetName )
234
260
if err != nil {
235
261
klog .Errorf ("failed to get vpc subnet %s, %v" , subnetName , err )
@@ -243,27 +269,17 @@ func (c *Controller) handleAddOvnDnatRule(key string) error {
243
269
}
244
270
245
271
vpcName := subnet .Spec .Vpc
246
- if cachedEip .Status .Type != "" && cachedEip .Status .Type != util .DnatUsingEip {
247
- err = fmt .Errorf ("failed to create ovn dnat %s, eip '%s' is using by %s" , key , eipName , cachedEip .Spec .Type )
248
- return err
249
- }
250
-
251
272
if err = c .patchOvnDnatStatus (key , vpcName , cachedEip .Status .V4Ip ,
252
273
internalV4Ip , mac , false ); err != nil {
253
274
klog .Errorf ("failed to patch status for dnat %s, %v" , key , err )
254
275
return err
255
276
}
256
277
257
- if err = c .handleAddOvnEipFinalizer (cachedEip , util .OvnDnatUseEipFinalizer ); err != nil {
278
+ if err = c .handleAddOvnEipFinalizer (cachedEip , util .OvnEipFinalizer ); err != nil {
258
279
klog .Errorf ("failed to add finalizer for ovn eip, %v" , err )
259
280
return err
260
281
}
261
282
262
- if err = c .handleAddOvnDnatFinalizer (cachedDnat ); err != nil {
263
- klog .Errorf ("failed to handle finalizer for ovn dnat, %v" , err )
264
- return err
265
- }
266
-
267
283
if err = c .AddDnatRule (vpcName , cachedDnat .Name , cachedEip .Status .V4Ip , internalV4Ip ,
268
284
cachedDnat .Spec .ExternalPort , cachedDnat .Spec .InternalPort , cachedDnat .Spec .Protocol ); err != nil {
269
285
klog .Errorf ("failed to create v4 dnat, %v" , err )
@@ -287,7 +303,7 @@ func (c *Controller) handleAddOvnDnatRule(key string) error {
287
303
return err
288
304
}
289
305
290
- if err = c .patchOvnEipNat (eipName , util . DnatUsingEip ); err != nil {
306
+ if err = c .patchOvnEipStatus (eipName , true ); err != nil {
291
307
klog .Errorf ("failed to patch status for eip %s, %v" , key , err )
292
308
return err
293
309
}
@@ -307,33 +323,19 @@ func (c *Controller) handleDelOvnDnatRule(key string) error {
307
323
308
324
eipName := cachedDnat .Spec .OvnEip
309
325
if len (eipName ) == 0 {
310
- klog .Errorf ("failed to delete ovn dnat, should set eip" )
311
- }
312
-
313
- cachedEip , err := c .GetOvnEip (eipName )
314
- if err != nil {
315
- klog .Errorf ("failed to get eip, %v" , err )
326
+ err := fmt .Errorf ("failed to create fip rule, should set eip" )
327
+ klog .Error (err )
316
328
return err
317
329
}
330
+
318
331
if cachedDnat .Status .Vpc != "" && cachedDnat .Status .V4Eip != "" && cachedDnat .Status .ExternalPort != "" {
319
332
if err = c .DelDnatRule (cachedDnat .Status .Vpc , cachedDnat .Name ,
320
333
cachedDnat .Status .V4Eip , cachedDnat .Status .ExternalPort ); err != nil {
321
334
klog .Errorf ("failed to delete dnat, %v" , err )
322
335
return err
323
336
}
324
337
}
325
-
326
- if err = c .handleDelOvnEipFinalizer (cachedEip , util .OvnDnatUseEipFinalizer ); err != nil {
327
- klog .Errorf ("failed to handle remove finalizer from ovn eip, %v" , err )
328
- return err
329
- }
330
338
c .resetOvnEipQueue .Add (cachedDnat .Spec .OvnEip )
331
-
332
- if err = c .handleDelOvnDnatFinalizer (cachedDnat ); err != nil {
333
- klog .Errorf ("failed to handle remove finalizer from ovn dnat, %v" , err )
334
- return err
335
- }
336
-
337
339
return nil
338
340
}
339
341
@@ -381,6 +383,16 @@ func (c *Controller) handleUpdateOvnDnatRule(key string) error {
381
383
return err
382
384
}
383
385
386
+ if cachedEip .Status .Type != "" && cachedEip .Status .Type != util .NatUsingEip {
387
+ err = fmt .Errorf ("ovn eip %s type is not %s, can not use" , cachedEip .Name , util .NatUsingEip )
388
+ return err
389
+ }
390
+
391
+ if _ , err := c .isOvnDnatDuplicated (eipName , key , cachedDnat .Spec .ExternalPort ); err != nil {
392
+ klog .Error ("failed to update dnat %s, %v" , cachedDnat .Name , err )
393
+ return err
394
+ }
395
+
384
396
subnet , err := c .subnetsLister .Get (subnetName )
385
397
if err != nil {
386
398
klog .Errorf ("failed to get vpc subnet %s, %v" , subnetName , err )
@@ -440,31 +452,6 @@ func (c *Controller) handleUpdateOvnDnatRule(key string) error {
440
452
return nil
441
453
}
442
454
443
- func (c * Controller ) handleAddOvnDnatFinalizer (cachedDnat * kubeovnv1.OvnDnatRule ) error {
444
- if cachedDnat .DeletionTimestamp .IsZero () {
445
- if util .ContainsString (cachedDnat .Finalizers , util .ControllerName ) {
446
- return nil
447
- }
448
- }
449
-
450
- newDnat := cachedDnat .DeepCopy ()
451
- controllerutil .AddFinalizer (newDnat , util .ControllerName )
452
- patch , err := util .GenerateMergePatchPayload (cachedDnat , newDnat )
453
- if err != nil {
454
- return err
455
- }
456
-
457
- if _ , err := c .config .KubeOvnClient .KubeovnV1 ().OvnDnatRules ().Patch (context .Background (), cachedDnat .Name ,
458
- types .MergePatchType , patch , metav1.PatchOptions {}, "" ); err != nil {
459
- if k8serrors .IsNotFound (err ) {
460
- return nil
461
- }
462
- klog .Errorf ("failed to add finalizer for ovn dnat '%s', %v" , cachedDnat .Name , err )
463
- return err
464
- }
465
- return nil
466
- }
467
-
468
455
func (c * Controller ) patchOvnDnatAnnotations (key , eipName string ) error {
469
456
oriDnat , err := c .ovnDnatRulesLister .Get (key )
470
457
if err != nil {
@@ -510,8 +497,31 @@ func (c *Controller) patchOvnDnatStatus(key, vpcName, v4Eip, podIp, podMac strin
510
497
}
511
498
return err
512
499
}
513
-
514
500
dnat := oriDnat .DeepCopy ()
501
+ needUpdateLabel := false
502
+ var op string
503
+ if len (dnat .Labels ) == 0 {
504
+ op = "add"
505
+ needUpdateLabel = true
506
+ dnat .Labels = map [string ]string {
507
+ util .EipV4IpLabel : v4Eip ,
508
+ }
509
+ } else if dnat .Labels [util .EipV4IpLabel ] != v4Eip {
510
+ op = "replace"
511
+ needUpdateLabel = true
512
+ dnat .Labels [util .EipV4IpLabel ] = v4Eip
513
+ }
514
+ if needUpdateLabel {
515
+ patchPayloadTemplate := `[{ "op": "%s", "path": "/metadata/labels", "value": %s }]`
516
+ raw , _ := json .Marshal (dnat .Labels )
517
+ patchPayload := fmt .Sprintf (patchPayloadTemplate , op , raw )
518
+ if _ , err := c .config .KubeOvnClient .KubeovnV1 ().OvnDnatRules ().Patch (context .Background (), dnat .Name ,
519
+ types .JSONPatchType , []byte (patchPayload ), metav1.PatchOptions {}); err != nil {
520
+ klog .Errorf ("failed to patch label for ovn dnat %s, %v" , dnat .Name , err )
521
+ return err
522
+ }
523
+ }
524
+
515
525
var changed bool
516
526
if dnat .Status .Ready != ready {
517
527
dnat .Status .Ready = ready
@@ -563,29 +573,6 @@ func (c *Controller) patchOvnDnatStatus(key, vpcName, v4Eip, podIp, podMac strin
563
573
return nil
564
574
}
565
575
566
- func (c * Controller ) handleDelOvnDnatFinalizer (cachedDnat * kubeovnv1.OvnDnatRule ) error {
567
- if len (cachedDnat .Finalizers ) == 0 {
568
- return nil
569
- }
570
-
571
- newDnat := cachedDnat .DeepCopy ()
572
- controllerutil .RemoveFinalizer (newDnat , util .ControllerName )
573
- patch , err := util .GenerateMergePatchPayload (cachedDnat , newDnat )
574
- if err != nil {
575
- return err
576
- }
577
-
578
- if _ , err := c .config .KubeOvnClient .KubeovnV1 ().OvnDnatRules ().Patch (context .Background (), cachedDnat .Name ,
579
- types .MergePatchType , patch , metav1.PatchOptions {}, "" ); err != nil {
580
- if k8serrors .IsNotFound (err ) {
581
- return nil
582
- }
583
- klog .Errorf ("failed to remove finalizer from ovn dnat '%s', %v" , cachedDnat .Name , err )
584
- return err
585
- }
586
- return nil
587
- }
588
-
589
576
func (c * Controller ) AddDnatRule (vpcName , dnatName , externalIp , internalIp , externalPort , internalPort , protocol string ) error {
590
577
externalEndpoint := net .JoinHostPort (externalIp , externalPort )
591
578
internalEndpoint := net .JoinHostPort (internalIp , internalPort )
0 commit comments