@@ -23,7 +23,7 @@ import (
23
23
"testing"
24
24
25
25
"github.com/stretchr/testify/assert"
26
- "k8s.io/api/core/v1"
26
+ v1 "k8s.io/api/core/v1"
27
27
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
28
28
"k8s.io/utils/exec"
29
29
)
@@ -253,6 +253,22 @@ func TestHostportManager(t *testing.T) {
253
253
},
254
254
expectError : false ,
255
255
},
256
+ {
257
+ mapping : & PodPortMapping {
258
+ Name : "pod3" ,
259
+ Namespace : "ns1" ,
260
+ IP : net .ParseIP ("2001:beef::2" ),
261
+ HostNetwork : false ,
262
+ PortMappings : []* PortMapping {
263
+ {
264
+ HostPort : 8443 ,
265
+ ContainerPort : 443 ,
266
+ Protocol : v1 .ProtocolTCP ,
267
+ },
268
+ },
269
+ },
270
+ expectError : true ,
271
+ },
256
272
}
257
273
258
274
// Add Hostports
@@ -362,3 +378,199 @@ func TestGetHostportChain(t *testing.T) {
362
378
t .Fatal (m )
363
379
}
364
380
}
381
+
382
+ func TestHostportManagerIPv6 (t * testing.T ) {
383
+ iptables := NewFakeIPTables ()
384
+ iptables .ipv6 = true
385
+ portOpener := NewFakeSocketManager ()
386
+ manager := & hostportManager {
387
+ hostPortMap : make (map [hostport ]closeable ),
388
+ iptables : iptables ,
389
+ portOpener : portOpener .openFakeSocket ,
390
+ execer : exec .New (),
391
+ }
392
+
393
+ testCases := []struct {
394
+ mapping * PodPortMapping
395
+ expectError bool
396
+ }{
397
+ {
398
+ mapping : & PodPortMapping {
399
+ Name : "pod1" ,
400
+ Namespace : "ns1" ,
401
+ IP : net .ParseIP ("2001:beef::2" ),
402
+ HostNetwork : false ,
403
+ PortMappings : []* PortMapping {
404
+ {
405
+ HostPort : 8080 ,
406
+ ContainerPort : 80 ,
407
+ Protocol : v1 .ProtocolTCP ,
408
+ },
409
+ {
410
+ HostPort : 8081 ,
411
+ ContainerPort : 81 ,
412
+ Protocol : v1 .ProtocolUDP ,
413
+ },
414
+ {
415
+ HostPort : 8083 ,
416
+ ContainerPort : 83 ,
417
+ Protocol : v1 .ProtocolSCTP ,
418
+ },
419
+ },
420
+ },
421
+ expectError : false ,
422
+ },
423
+ {
424
+ mapping : & PodPortMapping {
425
+ Name : "pod2" ,
426
+ Namespace : "ns1" ,
427
+ IP : net .ParseIP ("2001:beef::3" ),
428
+ HostNetwork : false ,
429
+ PortMappings : []* PortMapping {
430
+ {
431
+ HostPort : 8082 ,
432
+ ContainerPort : 80 ,
433
+ Protocol : v1 .ProtocolTCP ,
434
+ },
435
+ {
436
+ HostPort : 8081 ,
437
+ ContainerPort : 81 ,
438
+ Protocol : v1 .ProtocolUDP ,
439
+ },
440
+ {
441
+ HostPort : 8083 ,
442
+ ContainerPort : 83 ,
443
+ Protocol : v1 .ProtocolSCTP ,
444
+ },
445
+ },
446
+ },
447
+ expectError : true ,
448
+ },
449
+ {
450
+ mapping : & PodPortMapping {
451
+ Name : "pod3" ,
452
+ Namespace : "ns1" ,
453
+ IP : net .ParseIP ("2001:beef::4" ),
454
+ HostNetwork : false ,
455
+ PortMappings : []* PortMapping {
456
+ {
457
+ HostPort : 8443 ,
458
+ ContainerPort : 443 ,
459
+ Protocol : v1 .ProtocolTCP ,
460
+ },
461
+ },
462
+ },
463
+ expectError : false ,
464
+ },
465
+ {
466
+ mapping : & PodPortMapping {
467
+ Name : "pod4" ,
468
+ Namespace : "ns2" ,
469
+ IP : net .ParseIP ("192.168.2.2" ),
470
+ HostNetwork : false ,
471
+ PortMappings : []* PortMapping {
472
+ {
473
+ HostPort : 8443 ,
474
+ ContainerPort : 443 ,
475
+ Protocol : v1 .ProtocolTCP ,
476
+ },
477
+ },
478
+ },
479
+ expectError : true ,
480
+ },
481
+ }
482
+
483
+ // Add Hostports
484
+ for _ , tc := range testCases {
485
+ err := manager .Add ("id" , tc .mapping , "cbr0" )
486
+ if tc .expectError {
487
+ assert .Error (t , err )
488
+ continue
489
+ }
490
+ assert .NoError (t , err )
491
+ }
492
+
493
+ // Check port opened
494
+ expectedPorts := []hostport {{8080 , "tcp" }, {8081 , "udp" }, {8443 , "tcp" }}
495
+ openedPorts := make (map [hostport ]bool )
496
+ for hp , port := range portOpener .mem {
497
+ if ! port .closed {
498
+ openedPorts [hp ] = true
499
+ }
500
+ }
501
+ assert .EqualValues (t , len (openedPorts ), len (expectedPorts ))
502
+ for _ , hp := range expectedPorts {
503
+ _ , ok := openedPorts [hp ]
504
+ assert .EqualValues (t , true , ok )
505
+ }
506
+
507
+ // Check Iptables-save result after adding hostports
508
+ raw := bytes .NewBuffer (nil )
509
+ err := iptables .SaveInto (utiliptables .TableNAT , raw )
510
+ assert .NoError (t , err )
511
+
512
+ lines := strings .Split (string (raw .Bytes ()), "\n " )
513
+ expectedLines := map [string ]bool {
514
+ `*nat` : true ,
515
+ `:KUBE-HOSTPORTS - [0:0]` : true ,
516
+ `:OUTPUT - [0:0]` : true ,
517
+ `:PREROUTING - [0:0]` : true ,
518
+ `:POSTROUTING - [0:0]` : true ,
519
+ `:KUBE-HP-IJHALPHTORMHHPPK - [0:0]` : true ,
520
+ `:KUBE-HP-63UPIDJXVRSZGSUZ - [0:0]` : true ,
521
+ `:KUBE-HP-WFBOALXEP42XEMJK - [0:0]` : true ,
522
+ `:KUBE-HP-XU6AWMMJYOZOFTFZ - [0:0]` : true ,
523
+ "-A KUBE-HOSTPORTS -m comment --comment \" pod3_ns1 hostport 8443\" -m tcp -p tcp --dport 8443 -j KUBE-HP-WFBOALXEP42XEMJK" : true ,
524
+ "-A KUBE-HOSTPORTS -m comment --comment \" pod1_ns1 hostport 8081\" -m udp -p udp --dport 8081 -j KUBE-HP-63UPIDJXVRSZGSUZ" : true ,
525
+ "-A KUBE-HOSTPORTS -m comment --comment \" pod1_ns1 hostport 8080\" -m tcp -p tcp --dport 8080 -j KUBE-HP-IJHALPHTORMHHPPK" : true ,
526
+ "-A KUBE-HOSTPORTS -m comment --comment \" pod1_ns1 hostport 8083\" -m sctp -p sctp --dport 8083 -j KUBE-HP-XU6AWMMJYOZOFTFZ" : true ,
527
+ "-A OUTPUT -m comment --comment \" kube hostport portals\" -m addrtype --dst-type LOCAL -j KUBE-HOSTPORTS" : true ,
528
+ "-A PREROUTING -m comment --comment \" kube hostport portals\" -m addrtype --dst-type LOCAL -j KUBE-HOSTPORTS" : true ,
529
+ "-A POSTROUTING -m comment --comment \" SNAT for localhost access to hostports\" -o cbr0 -s ::1/128 -j MASQUERADE" : true ,
530
+ "-A KUBE-HP-IJHALPHTORMHHPPK -m comment --comment \" pod1_ns1 hostport 8080\" -s 2001:beef::2/32 -j KUBE-MARK-MASQ" : true ,
531
+ "-A KUBE-HP-IJHALPHTORMHHPPK -m comment --comment \" pod1_ns1 hostport 8080\" -m tcp -p tcp -j DNAT --to-destination [2001:beef::2]:80" : true ,
532
+ "-A KUBE-HP-63UPIDJXVRSZGSUZ -m comment --comment \" pod1_ns1 hostport 8081\" -s 2001:beef::2/32 -j KUBE-MARK-MASQ" : true ,
533
+ "-A KUBE-HP-63UPIDJXVRSZGSUZ -m comment --comment \" pod1_ns1 hostport 8081\" -m udp -p udp -j DNAT --to-destination [2001:beef::2]:81" : true ,
534
+ "-A KUBE-HP-XU6AWMMJYOZOFTFZ -m comment --comment \" pod1_ns1 hostport 8083\" -s 2001:beef::2/32 -j KUBE-MARK-MASQ" : true ,
535
+ "-A KUBE-HP-XU6AWMMJYOZOFTFZ -m comment --comment \" pod1_ns1 hostport 8083\" -m sctp -p sctp -j DNAT --to-destination [2001:beef::2]:83" : true ,
536
+ "-A KUBE-HP-WFBOALXEP42XEMJK -m comment --comment \" pod3_ns1 hostport 8443\" -s 2001:beef::4/32 -j KUBE-MARK-MASQ" : true ,
537
+ "-A KUBE-HP-WFBOALXEP42XEMJK -m comment --comment \" pod3_ns1 hostport 8443\" -m tcp -p tcp -j DNAT --to-destination [2001:beef::4]:443" : true ,
538
+ `COMMIT` : true ,
539
+ }
540
+ for _ , line := range lines {
541
+ if len (strings .TrimSpace (line )) > 0 {
542
+ _ , ok := expectedLines [strings .TrimSpace (line )]
543
+ assert .EqualValues (t , true , ok )
544
+ }
545
+ }
546
+
547
+ // Remove all added hostports
548
+ for _ , tc := range testCases {
549
+ if ! tc .expectError {
550
+ err := manager .Remove ("id" , tc .mapping )
551
+ assert .NoError (t , err )
552
+ }
553
+ }
554
+
555
+ // Check Iptables-save result after deleting hostports
556
+ raw .Reset ()
557
+ err = iptables .SaveInto (utiliptables .TableNAT , raw )
558
+ assert .NoError (t , err )
559
+ lines = strings .Split (string (raw .Bytes ()), "\n " )
560
+ remainingChains := make (map [string ]bool )
561
+ for _ , line := range lines {
562
+ if strings .HasPrefix (line , ":" ) {
563
+ remainingChains [strings .TrimSpace (line )] = true
564
+ }
565
+ }
566
+ expectDeletedChains := []string {"KUBE-HP-4YVONL46AKYWSKS3" , "KUBE-HP-7THKRFSEH4GIIXK7" , "KUBE-HP-5N7UH5JAXCVP5UJR" }
567
+ for _ , chain := range expectDeletedChains {
568
+ _ , ok := remainingChains [chain ]
569
+ assert .EqualValues (t , false , ok )
570
+ }
571
+
572
+ // check if all ports are closed
573
+ for _ , port := range portOpener .mem {
574
+ assert .EqualValues (t , true , port .closed )
575
+ }
576
+ }
0 commit comments