2015-08-11 02:47:13 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2015 The Kubernetes Authors .
2015-08-11 02:47:13 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package iptables
import (
2017-05-18 09:55:43 +00:00
"bytes"
2017-12-10 07:12:23 +00:00
"fmt"
"net"
2017-04-01 19:55:29 +00:00
"reflect"
2017-02-04 02:03:45 +00:00
"strconv"
2017-12-10 07:12:23 +00:00
"strings"
2015-08-11 02:47:13 +00:00
"testing"
2017-05-22 04:44:45 +00:00
"time"
2015-09-17 22:21:55 +00:00
2017-10-06 22:59:37 +00:00
"github.com/golang/glog"
2017-02-01 20:47:29 +00:00
2018-08-15 13:51:19 +00:00
"k8s.io/api/core/v1"
2017-01-17 03:38:19 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2017-01-11 14:09:48 +00:00
"k8s.io/apimachinery/pkg/types"
2017-01-27 20:42:17 +00:00
"k8s.io/apimachinery/pkg/util/intstr"
2016-04-13 00:45:39 +00:00
"k8s.io/kubernetes/pkg/proxy"
2017-08-22 02:49:24 +00:00
utilproxy "k8s.io/kubernetes/pkg/proxy/util"
2018-01-17 02:30:19 +00:00
utilproxytest "k8s.io/kubernetes/pkg/proxy/util/testing"
2017-05-22 04:44:45 +00:00
"k8s.io/kubernetes/pkg/util/async"
2018-02-01 02:20:22 +00:00
"k8s.io/kubernetes/pkg/util/conntrack"
2015-09-17 22:21:55 +00:00
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
2016-09-27 02:48:21 +00:00
iptablestest "k8s.io/kubernetes/pkg/util/iptables/testing"
2017-07-19 05:58:53 +00:00
"k8s.io/utils/exec"
fakeexec "k8s.io/utils/exec/testing"
2015-08-11 02:47:13 +00:00
)
func checkAllLines ( t * testing . T , table utiliptables . Table , save [ ] byte , expectedLines map [ utiliptables . Chain ] string ) {
2016-05-11 20:25:14 +00:00
chainLines := utiliptables . GetChainLines ( table , save )
2018-07-06 11:34:15 +00:00
for chain , lineBytes := range chainLines {
line := string ( lineBytes )
2015-08-11 02:47:13 +00:00
if expected , exists := expectedLines [ chain ] ; exists {
if expected != line {
t . Errorf ( "getChainLines expected chain line not present. For chain: %s Expected: %s Got: %s" , chain , expected , line )
}
} else {
t . Errorf ( "getChainLines expected chain not present: %s" , chain )
}
}
}
2016-02-02 22:19:16 +00:00
func TestGetChainLines ( t * testing . T ) {
2017-10-06 22:59:37 +00:00
iptablesSave := ` # Generated by iptables - save v1 .4 .7 on Wed Oct 29 14 : 56 : 01 2014
2015-08-11 02:47:13 +00:00
* nat
: PREROUTING ACCEPT [ 2136997 : 197881818 ]
: POSTROUTING ACCEPT [ 4284525 : 258542680 ]
: OUTPUT ACCEPT [ 5901660 : 357267963 ]
- A PREROUTING - m addrtype -- dst - type LOCAL - j DOCKER
COMMIT
# Completed on Wed Oct 29 14 : 56 : 01 2014 `
expected := map [ utiliptables . Chain ] string {
utiliptables . ChainPrerouting : ":PREROUTING ACCEPT [2136997:197881818]" ,
utiliptables . ChainPostrouting : ":POSTROUTING ACCEPT [4284525:258542680]" ,
utiliptables . ChainOutput : ":OUTPUT ACCEPT [5901660:357267963]" ,
}
2017-10-06 22:59:37 +00:00
checkAllLines ( t , utiliptables . TableNAT , [ ] byte ( iptablesSave ) , expected )
2015-08-11 02:47:13 +00:00
}
2016-02-02 22:19:16 +00:00
func TestGetChainLinesMultipleTables ( t * testing . T ) {
2017-10-06 22:59:37 +00:00
iptablesSave := ` # Generated by iptables - save v1 .4 .21 on Fri Aug 7 14 : 47 : 37 2015
2015-08-11 02:47:13 +00:00
* nat
: PREROUTING ACCEPT [ 2 : 138 ]
: INPUT ACCEPT [ 0 : 0 ]
: OUTPUT ACCEPT [ 0 : 0 ]
: POSTROUTING ACCEPT [ 0 : 0 ]
: DOCKER - [ 0 : 0 ]
: KUBE - NODEPORT - CONTAINER - [ 0 : 0 ]
: KUBE - NODEPORT - HOST - [ 0 : 0 ]
: KUBE - PORTALS - CONTAINER - [ 0 : 0 ]
: KUBE - PORTALS - HOST - [ 0 : 0 ]
2016-02-02 22:19:16 +00:00
: KUBE - SVC - 1111111111111111 - [ 0 : 0 ]
: KUBE - SVC - 2222222222222222 - [ 0 : 0 ]
: KUBE - SVC - 3333333333333333 - [ 0 : 0 ]
: KUBE - SVC - 4444444444444444 - [ 0 : 0 ]
: KUBE - SVC - 5555555555555555 - [ 0 : 0 ]
: KUBE - SVC - 6666666666666666 - [ 0 : 0 ]
2015-08-11 02:47:13 +00:00
- A PREROUTING - m comment -- comment "handle ClusterIPs; NOTE: this must be before the NodePort rules" - j KUBE - PORTALS - CONTAINER
- A PREROUTING - m addrtype -- dst - type LOCAL - j DOCKER
- A PREROUTING - m addrtype -- dst - type LOCAL - m comment -- comment "handle service NodePorts; NOTE: this must be the last rule in the chain" - j KUBE - NODEPORT - CONTAINER
- A OUTPUT - m comment -- comment "handle ClusterIPs; NOTE: this must be before the NodePort rules" - j KUBE - PORTALS - HOST
- A OUTPUT ! - d 127.0 .0 .0 / 8 - m addrtype -- dst - type LOCAL - j DOCKER
- A OUTPUT - m addrtype -- dst - type LOCAL - m comment -- comment "handle service NodePorts; NOTE: this must be the last rule in the chain" - j KUBE - NODEPORT - HOST
- A POSTROUTING - s 10.246 .1 .0 / 24 ! - o cbr0 - j MASQUERADE
- A POSTROUTING - s 10.0 .2 .15 / 32 - d 10.0 .2 .15 / 32 - m comment -- comment "handle pod connecting to self" - j MASQUERADE
2016-02-02 22:19:16 +00:00
- A KUBE - PORTALS - CONTAINER - d 10.247 .0 .1 / 32 - p tcp - m comment -- comment "portal for default/kubernetes:" - m state -- state NEW - m tcp -- dport 443 - j KUBE - SVC - 5555555555555555
- A KUBE - PORTALS - CONTAINER - d 10.247 .0 .10 / 32 - p udp - m comment -- comment "portal for kube-system/kube-dns:dns" - m state -- state NEW - m udp -- dport 53 - j KUBE - SVC - 6666666666666666
- A KUBE - PORTALS - CONTAINER - d 10.247 .0 .10 / 32 - p tcp - m comment -- comment "portal for kube-system/kube-dns:dns-tcp" - m state -- state NEW - m tcp -- dport 53 - j KUBE - SVC - 2222222222222222
- A KUBE - PORTALS - HOST - d 10.247 .0 .1 / 32 - p tcp - m comment -- comment "portal for default/kubernetes:" - m state -- state NEW - m tcp -- dport 443 - j KUBE - SVC - 5555555555555555
- A KUBE - PORTALS - HOST - d 10.247 .0 .10 / 32 - p udp - m comment -- comment "portal for kube-system/kube-dns:dns" - m state -- state NEW - m udp -- dport 53 - j KUBE - SVC - 6666666666666666
- A KUBE - PORTALS - HOST - d 10.247 .0 .10 / 32 - p tcp - m comment -- comment "portal for kube-system/kube-dns:dns-tcp" - m state -- state NEW - m tcp -- dport 53 - j KUBE - SVC - 2222222222222222
- A KUBE - SVC - 1111111111111111 - p udp - m comment -- comment "kube-system/kube-dns:dns" - m recent -- set -- name KUBE - SVC - 1111111111111111 -- mask 255.255 .255 .255 -- rsource - j DNAT -- to - destination 10.246 .1 .2 : 53
- A KUBE - SVC - 2222222222222222 - m comment -- comment "kube-system/kube-dns:dns-tcp" - j KUBE - SVC - 3333333333333333
- A KUBE - SVC - 3333333333333333 - p tcp - m comment -- comment "kube-system/kube-dns:dns-tcp" - m recent -- set -- name KUBE - SVC - 3333333333333333 -- mask 255.255 .255 .255 -- rsource - j DNAT -- to - destination 10.246 .1 .2 : 53
- A KUBE - SVC - 4444444444444444 - p tcp - m comment -- comment "default/kubernetes:" - m recent -- set -- name KUBE - SVC - 4444444444444444 -- mask 255.255 .255 .255 -- rsource - j DNAT -- to - destination 10.245 .1 .2 : 443
- A KUBE - SVC - 5555555555555555 - m comment -- comment "default/kubernetes:" - j KUBE - SVC - 4444444444444444
- A KUBE - SVC - 6666666666666666 - m comment -- comment "kube-system/kube-dns:dns" - j KUBE - SVC - 1111111111111111
2015-08-11 02:47:13 +00:00
COMMIT
# Completed on Fri Aug 7 14 : 47 : 37 2015
# Generated by iptables - save v1 .4 .21 on Fri Aug 7 14 : 47 : 37 2015
* filter
: INPUT ACCEPT [ 17514 : 83115836 ]
: FORWARD ACCEPT [ 0 : 0 ]
: OUTPUT ACCEPT [ 8909 : 688225 ]
: DOCKER - [ 0 : 0 ]
- A FORWARD - o cbr0 - j DOCKER
- A FORWARD - o cbr0 - m conntrack -- ctstate RELATED , ESTABLISHED - j ACCEPT
- A FORWARD - i cbr0 ! - o cbr0 - j ACCEPT
- A FORWARD - i cbr0 - o cbr0 - j ACCEPT
COMMIT
`
expected := map [ utiliptables . Chain ] string {
2016-02-02 22:19:16 +00:00
utiliptables . ChainPrerouting : ":PREROUTING ACCEPT [2:138]" ,
utiliptables . Chain ( "INPUT" ) : ":INPUT ACCEPT [0:0]" ,
utiliptables . Chain ( "OUTPUT" ) : ":OUTPUT ACCEPT [0:0]" ,
utiliptables . ChainPostrouting : ":POSTROUTING ACCEPT [0:0]" ,
utiliptables . Chain ( "DOCKER" ) : ":DOCKER - [0:0]" ,
utiliptables . Chain ( "KUBE-NODEPORT-CONTAINER" ) : ":KUBE-NODEPORT-CONTAINER - [0:0]" ,
utiliptables . Chain ( "KUBE-NODEPORT-HOST" ) : ":KUBE-NODEPORT-HOST - [0:0]" ,
utiliptables . Chain ( "KUBE-PORTALS-CONTAINER" ) : ":KUBE-PORTALS-CONTAINER - [0:0]" ,
utiliptables . Chain ( "KUBE-PORTALS-HOST" ) : ":KUBE-PORTALS-HOST - [0:0]" ,
utiliptables . Chain ( "KUBE-SVC-1111111111111111" ) : ":KUBE-SVC-1111111111111111 - [0:0]" ,
utiliptables . Chain ( "KUBE-SVC-2222222222222222" ) : ":KUBE-SVC-2222222222222222 - [0:0]" ,
utiliptables . Chain ( "KUBE-SVC-3333333333333333" ) : ":KUBE-SVC-3333333333333333 - [0:0]" ,
utiliptables . Chain ( "KUBE-SVC-4444444444444444" ) : ":KUBE-SVC-4444444444444444 - [0:0]" ,
utiliptables . Chain ( "KUBE-SVC-5555555555555555" ) : ":KUBE-SVC-5555555555555555 - [0:0]" ,
utiliptables . Chain ( "KUBE-SVC-6666666666666666" ) : ":KUBE-SVC-6666666666666666 - [0:0]" ,
2015-08-11 02:47:13 +00:00
}
2017-10-06 22:59:37 +00:00
checkAllLines ( t , utiliptables . TableNAT , [ ] byte ( iptablesSave ) , expected )
2015-08-11 02:47:13 +00:00
}
2016-02-02 22:19:16 +00:00
2018-08-15 13:51:19 +00:00
func newFakeServiceInfo ( service proxy . ServicePortName , ip net . IP , port int , protocol v1 . Protocol , onlyNodeLocalEndpoints bool ) * serviceInfo {
2016-04-13 00:45:39 +00:00
return & serviceInfo {
2018-02-24 21:32:55 +00:00
BaseServiceInfo : & proxy . BaseServiceInfo {
2018-08-15 13:51:19 +00:00
SessionAffinityType : v1 . ServiceAffinityNone , // default
StickyMaxAgeSeconds : int ( v1 . DefaultClientIPServiceAffinitySeconds ) , // default
2018-02-17 03:09:33 +00:00
ClusterIP : ip ,
Port : port ,
Protocol : protocol ,
OnlyNodeLocalEndpoints : onlyNodeLocalEndpoints ,
} ,
2016-04-13 00:45:39 +00:00
}
}
func TestDeleteEndpointConnections ( t * testing . T ) {
2017-10-06 22:59:37 +00:00
const (
2018-08-25 20:26:25 +00:00
UDP = v1 . ProtocolUDP
TCP = v1 . ProtocolTCP
SCTP = v1 . ProtocolSCTP
2017-10-06 22:59:37 +00:00
)
testCases := [ ] struct {
description string
svcName string
svcIP string
svcPort int
2018-08-15 13:51:19 +00:00
protocol v1 . Protocol
2017-12-10 07:12:23 +00:00
endpoint string // IP:port endpoint
epSvcPair proxy . ServiceEndpoint // Will be generated by test
2017-10-06 22:59:37 +00:00
simulatedErr string
} {
{
description : "V4 UDP" ,
svcName : "v4-udp" ,
svcIP : "10.96.1.1" ,
svcPort : 80 ,
protocol : UDP ,
endpoint : "10.240.0.3:80" ,
} , {
description : "V4 TCP" ,
svcName : "v4-tcp" ,
svcIP : "10.96.2.2" ,
svcPort : 80 ,
protocol : TCP ,
endpoint : "10.240.0.4:80" ,
2018-06-11 11:25:18 +00:00
} , {
description : "V4 SCTP" ,
svcName : "v4-sctp" ,
svcIP : "10.96.3.3" ,
svcPort : 80 ,
protocol : SCTP ,
endpoint : "10.240.0.5:80" ,
} , {
2017-10-06 22:59:37 +00:00
description : "V4 UDP, nothing to delete, benign error" ,
svcName : "v4-udp-nothing-to-delete" ,
svcIP : "10.96.1.1" ,
svcPort : 80 ,
protocol : UDP ,
endpoint : "10.240.0.3:80" ,
2018-02-01 02:20:22 +00:00
simulatedErr : conntrack . NoConnectionToDelete ,
2017-10-06 22:59:37 +00:00
} , {
description : "V4 UDP, unexpected error, should be glogged" ,
svcName : "v4-udp-simulated-error" ,
svcIP : "10.96.1.1" ,
svcPort : 80 ,
protocol : UDP ,
endpoint : "10.240.0.3:80" ,
simulatedErr : "simulated error" ,
} , {
description : "V6 UDP" ,
svcName : "v6-udp" ,
svcIP : "fd00:1234::20" ,
svcPort : 80 ,
protocol : UDP ,
endpoint : "[2001:db8::2]:80" ,
} , {
description : "V6 TCP" ,
svcName : "v6-tcp" ,
svcIP : "fd00:1234::30" ,
svcPort : 80 ,
protocol : TCP ,
endpoint : "[2001:db8::3]:80" ,
2018-06-11 11:25:18 +00:00
} , {
description : "V6 SCTP" ,
svcName : "v6-sctp" ,
svcIP : "fd00:1234::40" ,
svcPort : 80 ,
protocol : SCTP ,
endpoint : "[2001:db8::4]:80" ,
2016-04-13 00:45:39 +00:00
} ,
}
2017-10-06 22:59:37 +00:00
// Create a service map that has service info entries for all test cases
// and generate an endpoint service pair for each test case
2017-12-10 07:12:23 +00:00
serviceMap := make ( map [ proxy . ServicePortName ] proxy . ServicePort )
2017-10-06 22:59:37 +00:00
for i , tc := range testCases {
svc := proxy . ServicePortName {
NamespacedName : types . NamespacedName { Namespace : "ns1" , Name : tc . svcName } ,
Port : "p80" ,
}
serviceMap [ svc ] = newFakeServiceInfo ( svc , net . ParseIP ( tc . svcIP ) , 80 , tc . protocol , false )
2017-12-10 07:12:23 +00:00
testCases [ i ] . epSvcPair = proxy . ServiceEndpoint {
Endpoint : tc . endpoint ,
ServicePortName : svc ,
2017-10-06 22:59:37 +00:00
}
}
// Create a fake executor for the conntrack utility. This should only be
// invoked for UDP connections, since no conntrack cleanup is needed for TCP
fcmd := fakeexec . FakeCmd { }
2017-07-19 05:58:53 +00:00
fexec := fakeexec . FakeExec {
2016-04-13 00:45:39 +00:00
LookPathFunc : func ( cmd string ) ( string , error ) { return cmd , nil } ,
}
2017-10-06 22:59:37 +00:00
execFunc := func ( cmd string , args ... string ) exec . Cmd {
return fakeexec . InitFakeCmd ( & fcmd , cmd , args ... )
}
for _ , tc := range testCases {
if tc . protocol == UDP {
var cmdOutput string
var simErr error
if tc . simulatedErr == "" {
cmdOutput = "1 flow entries have been deleted"
} else {
simErr = fmt . Errorf ( tc . simulatedErr )
}
cmdFunc := func ( ) ( [ ] byte , error ) { return [ ] byte ( cmdOutput ) , simErr }
fcmd . CombinedOutputScript = append ( fcmd . CombinedOutputScript , cmdFunc )
fexec . CommandScript = append ( fexec . CommandScript , execFunc )
}
}
2016-04-13 00:45:39 +00:00
2017-10-06 22:59:37 +00:00
// Create a proxier using the fake conntrack executor and service map
2016-04-13 00:45:39 +00:00
fakeProxier := Proxier { exec : & fexec , serviceMap : serviceMap }
2017-10-06 22:59:37 +00:00
// Run the test cases
for _ , tc := range testCases {
priorExecs := fexec . CommandCalls
priorGlogErrs := glog . Stats . Error . Lines ( )
2016-04-13 00:45:39 +00:00
2017-12-10 07:12:23 +00:00
input := [ ] proxy . ServiceEndpoint { tc . epSvcPair }
2016-04-13 00:45:39 +00:00
fakeProxier . deleteEndpointConnections ( input )
2017-10-06 22:59:37 +00:00
// For UDP connections, check the executed conntrack command
var expExecs int
if tc . protocol == UDP {
isIPv6 := func ( ip string ) bool {
netIP := net . ParseIP ( ip )
if netIP . To4 ( ) == nil {
return true
}
return false
}
endpointIP := utilproxy . IPPart ( tc . endpoint )
expectCommand := fmt . Sprintf ( "conntrack -D --orig-dst %s --dst-nat %s -p udp" , tc . svcIP , endpointIP )
if isIPv6 ( endpointIP ) {
expectCommand += " -f ipv6"
}
actualCommand := strings . Join ( fcmd . CombinedOutputLog [ fexec . CommandCalls - 1 ] , " " )
if actualCommand != expectCommand {
t . Errorf ( "%s: Expected command: %s, but executed %s" , tc . description , expectCommand , actualCommand )
2016-04-13 00:45:39 +00:00
}
2017-10-06 22:59:37 +00:00
expExecs = 1
2016-04-13 00:45:39 +00:00
}
2017-10-06 22:59:37 +00:00
// Check the number of times conntrack was executed
execs := fexec . CommandCalls - priorExecs
if execs != expExecs {
t . Errorf ( "%s: Expected conntrack to be executed %d times, but got %d" , tc . description , expExecs , execs )
}
// Check the number of new glog errors
var expGlogErrs int64
2018-02-01 02:20:22 +00:00
if tc . simulatedErr != "" && tc . simulatedErr != conntrack . NoConnectionToDelete {
2017-10-06 22:59:37 +00:00
expGlogErrs = 1
}
glogErrs := glog . Stats . Error . Lines ( ) - priorGlogErrs
if glogErrs != expGlogErrs {
t . Errorf ( "%s: Expected %d glogged errors, but got %d" , tc . description , expGlogErrs , glogErrs )
2016-04-13 00:45:39 +00:00
}
}
}
2016-04-22 23:13:06 +00:00
type fakeClosable struct {
closed bool
}
func ( c * fakeClosable ) Close ( ) error {
c . closed = true
return nil
}
2016-09-27 02:48:21 +00:00
// fakePortOpener implements portOpener.
type fakePortOpener struct {
2017-08-22 02:49:24 +00:00
openPorts [ ] * utilproxy . LocalPort
2016-09-27 02:48:21 +00:00
}
// OpenLocalPort fakes out the listen() and bind() used by syncProxyRules
// to lock a local port.
2017-08-22 02:49:24 +00:00
func ( f * fakePortOpener ) OpenLocalPort ( lp * utilproxy . LocalPort ) ( utilproxy . Closeable , error ) {
2016-09-27 02:48:21 +00:00
f . openPorts = append ( f . openPorts , lp )
return nil , nil
}
2017-04-01 19:55:29 +00:00
type fakeHealthChecker struct {
2017-04-02 04:14:30 +00:00
services map [ types . NamespacedName ] uint16
endpoints map [ types . NamespacedName ] int
2017-04-01 19:55:29 +00:00
}
2017-02-04 02:45:52 +00:00
2017-04-01 19:55:29 +00:00
func newFakeHealthChecker ( ) * fakeHealthChecker {
return & fakeHealthChecker {
2017-04-02 04:14:30 +00:00
services : map [ types . NamespacedName ] uint16 { } ,
endpoints : map [ types . NamespacedName ] int { } ,
2017-04-01 19:55:29 +00:00
}
}
2017-04-02 04:14:30 +00:00
func ( fake * fakeHealthChecker ) SyncServices ( newServices map [ types . NamespacedName ] uint16 ) error {
fake . services = newServices
return nil
}
func ( fake * fakeHealthChecker ) SyncEndpoints ( newEndpoints map [ types . NamespacedName ] int ) error {
fake . endpoints = newEndpoints
return nil
2017-04-01 19:55:29 +00:00
}
2017-02-04 02:45:52 +00:00
2017-02-04 02:03:45 +00:00
const testHostname = "test-hostname"
2016-09-27 02:48:21 +00:00
func NewFakeProxier ( ipt utiliptables . Interface ) * Proxier {
// TODO: Call NewProxier after refactoring out the goroutine
// invocation into a Run() method.
2017-05-22 04:44:45 +00:00
p := & Proxier {
2017-07-19 05:58:53 +00:00
exec : & fakeexec . FakeExec { } ,
2017-12-10 07:12:23 +00:00
serviceMap : make ( proxy . ServiceMap ) ,
2018-02-24 21:32:55 +00:00
serviceChanges : proxy . NewServiceChangeTracker ( newServiceInfo , nil , nil ) ,
2017-12-10 07:12:23 +00:00
endpointsMap : make ( proxy . EndpointsMap ) ,
2018-02-24 21:32:55 +00:00
endpointsChanges : proxy . NewEndpointChangeTracker ( testHostname , newEndpointInfo , nil , nil ) ,
2017-05-24 14:16:39 +00:00
iptables : ipt ,
clusterCIDR : "10.0.0.0/24" ,
hostname : testHostname ,
2017-08-22 02:49:24 +00:00
portsMap : make ( map [ utilproxy . LocalPort ] utilproxy . Closeable ) ,
portMapper : & fakePortOpener { [ ] * utilproxy . LocalPort { } } ,
2017-05-24 14:16:39 +00:00
healthChecker : newFakeHealthChecker ( ) ,
2017-05-24 10:53:11 +00:00
precomputedProbabilities : make ( [ ] string , 0 , 1001 ) ,
2017-05-24 14:16:39 +00:00
iptablesData : bytes . NewBuffer ( nil ) ,
filterChains : bytes . NewBuffer ( nil ) ,
filterRules : bytes . NewBuffer ( nil ) ,
natChains : bytes . NewBuffer ( nil ) ,
natRules : bytes . NewBuffer ( nil ) ,
2018-01-17 02:30:19 +00:00
nodePortAddresses : make ( [ ] string , 0 ) ,
networkInterfacer : utilproxytest . NewFakeNetwork ( ) ,
2016-09-27 02:48:21 +00:00
}
2017-05-22 04:44:45 +00:00
p . syncRunner = async . NewBoundedFrequencyRunner ( "test-sync-runner" , p . syncProxyRules , 0 , time . Minute , 1 )
return p
2016-09-27 02:48:21 +00:00
}
2017-11-11 02:42:07 +00:00
func hasSessionAffinityRule ( rules [ ] iptablestest . Rule ) bool {
for _ , r := range rules {
if _ , ok := r [ iptablestest . Recent ] ; ok {
return true
}
}
return false
}
2017-02-04 02:03:45 +00:00
func hasJump ( rules [ ] iptablestest . Rule , destChain , destIP string , destPort int ) bool {
destPortStr := strconv . Itoa ( destPort )
2016-11-02 11:25:07 +00:00
match := false
2016-09-27 02:48:21 +00:00
for _ , r := range rules {
if r [ iptablestest . Jump ] == destChain {
2016-11-02 11:25:07 +00:00
match = true
2016-09-27 02:48:21 +00:00
if destIP != "" {
2017-02-04 02:03:45 +00:00
if strings . Contains ( r [ iptablestest . Destination ] , destIP ) && ( strings . Contains ( r [ iptablestest . DPort ] , destPortStr ) || r [ iptablestest . DPort ] == "" ) {
2016-11-02 11:25:07 +00:00
return true
}
match = false
2016-09-27 02:48:21 +00:00
}
2017-02-04 02:03:45 +00:00
if destPort != 0 {
if strings . Contains ( r [ iptablestest . DPort ] , destPortStr ) && ( strings . Contains ( r [ iptablestest . Destination ] , destIP ) || r [ iptablestest . Destination ] == "" ) {
2016-11-02 11:25:07 +00:00
return true
}
match = false
2016-09-27 02:48:21 +00:00
}
}
}
2016-11-02 11:25:07 +00:00
return match
}
func TestHasJump ( t * testing . T ) {
testCases := map [ string ] struct {
rules [ ] iptablestest . Rule
destChain string
destIP string
2017-02-04 02:03:45 +00:00
destPort int
2016-11-02 11:25:07 +00:00
expected bool
} {
"case 1" : {
// Match the 1st rule(both dest IP and dest Port)
rules : [ ] iptablestest . Rule {
{ "-d " : "10.20.30.41/32" , "--dport " : "80" , "-p " : "tcp" , "-j " : "REJECT" } ,
{ "--dport " : "3001" , "-p " : "tcp" , "-j " : "KUBE-MARK-MASQ" } ,
} ,
destChain : "REJECT" ,
destIP : "10.20.30.41" ,
2017-02-04 02:03:45 +00:00
destPort : 80 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 2" : {
// Match the 2nd rule(dest Port)
rules : [ ] iptablestest . Rule {
{ "-d " : "10.20.30.41/32" , "-p " : "tcp" , "-j " : "REJECT" } ,
{ "--dport " : "3001" , "-p " : "tcp" , "-j " : "REJECT" } ,
} ,
destChain : "REJECT" ,
destIP : "" ,
2017-02-04 02:03:45 +00:00
destPort : 3001 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 3" : {
// Match both dest IP and dest Port
rules : [ ] iptablestest . Rule {
{ "-d " : "1.2.3.4/32" , "--dport " : "80" , "-p " : "tcp" , "-j " : "KUBE-XLB-GF53O3C2HZEXL2XN" } ,
} ,
destChain : "KUBE-XLB-GF53O3C2HZEXL2XN" ,
destIP : "1.2.3.4" ,
2017-02-04 02:03:45 +00:00
destPort : 80 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 4" : {
// Match dest IP but doesn't match dest Port
rules : [ ] iptablestest . Rule {
{ "-d " : "1.2.3.4/32" , "--dport " : "80" , "-p " : "tcp" , "-j " : "KUBE-XLB-GF53O3C2HZEXL2XN" } ,
} ,
destChain : "KUBE-XLB-GF53O3C2HZEXL2XN" ,
destIP : "1.2.3.4" ,
2017-02-04 02:03:45 +00:00
destPort : 8080 ,
2016-11-02 11:25:07 +00:00
expected : false ,
} ,
"case 5" : {
// Match dest Port but doesn't match dest IP
rules : [ ] iptablestest . Rule {
{ "-d " : "1.2.3.4/32" , "--dport " : "80" , "-p " : "tcp" , "-j " : "KUBE-XLB-GF53O3C2HZEXL2XN" } ,
} ,
destChain : "KUBE-XLB-GF53O3C2HZEXL2XN" ,
destIP : "10.20.30.40" ,
2017-02-04 02:03:45 +00:00
destPort : 80 ,
2016-11-02 11:25:07 +00:00
expected : false ,
} ,
"case 6" : {
// Match the 2nd rule(dest IP)
rules : [ ] iptablestest . Rule {
{ "-d " : "10.20.30.41/32" , "-p " : "tcp" , "-j " : "REJECT" } ,
{ "-d " : "1.2.3.4/32" , "-p " : "tcp" , "-j " : "REJECT" } ,
{ "--dport " : "3001" , "-p " : "tcp" , "-j " : "REJECT" } ,
} ,
destChain : "REJECT" ,
destIP : "1.2.3.4" ,
2017-02-04 02:03:45 +00:00
destPort : 8080 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 7" : {
// Match the 2nd rule(dest Port)
rules : [ ] iptablestest . Rule {
{ "-d " : "10.20.30.41/32" , "-p " : "tcp" , "-j " : "REJECT" } ,
{ "--dport " : "3001" , "-p " : "tcp" , "-j " : "REJECT" } ,
} ,
destChain : "REJECT" ,
destIP : "1.2.3.4" ,
2017-02-04 02:03:45 +00:00
destPort : 3001 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 8" : {
// Match the 1st rule(dest IP)
rules : [ ] iptablestest . Rule {
{ "-d " : "10.20.30.41/32" , "-p " : "tcp" , "-j " : "REJECT" } ,
{ "--dport " : "3001" , "-p " : "tcp" , "-j " : "REJECT" } ,
} ,
destChain : "REJECT" ,
destIP : "10.20.30.41" ,
2017-02-04 02:03:45 +00:00
destPort : 8080 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 9" : {
rules : [ ] iptablestest . Rule {
{ "-j " : "KUBE-SEP-LWSOSDSHMKPJHHJV" } ,
} ,
destChain : "KUBE-SEP-LWSOSDSHMKPJHHJV" ,
destIP : "" ,
2017-02-04 02:03:45 +00:00
destPort : 0 ,
2016-11-02 11:25:07 +00:00
expected : true ,
} ,
"case 10" : {
rules : [ ] iptablestest . Rule {
{ "-j " : "KUBE-SEP-FOO" } ,
} ,
destChain : "KUBE-SEP-BAR" ,
destIP : "" ,
2017-02-04 02:03:45 +00:00
destPort : 0 ,
2016-11-02 11:25:07 +00:00
expected : false ,
} ,
}
for k , tc := range testCases {
if got := hasJump ( tc . rules , tc . destChain , tc . destIP , tc . destPort ) ; got != tc . expected {
t . Errorf ( "%v: expected %v, got %v" , k , tc . expected , got )
}
}
2016-09-27 02:48:21 +00:00
}
func hasDNAT ( rules [ ] iptablestest . Rule , endpoint string ) bool {
for _ , r := range rules {
if r [ iptablestest . ToDest ] == endpoint {
return true
}
}
return false
}
func errorf ( msg string , rules [ ] iptablestest . Rule , t * testing . T ) {
for _ , r := range rules {
2017-04-03 06:21:03 +00:00
t . Logf ( "%q" , r )
2016-09-27 02:48:21 +00:00
}
t . Errorf ( "%v" , msg )
}
func TestClusterIPReject ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
} }
} ) ,
2017-04-14 13:28:52 +00:00
)
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp )
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2016-09-27 02:48:21 +00:00
2018-08-15 13:51:19 +00:00
svcChain := string ( servicePortChainName ( svcPortName . String ( ) , strings . ToLower ( string ( v1 . ProtocolTCP ) ) ) )
2016-09-27 02:48:21 +00:00
svcRules := ipt . GetRules ( svcChain )
if len ( svcRules ) != 0 {
2017-04-03 06:21:03 +00:00
errorf ( fmt . Sprintf ( "Unexpected rule for chain %v service %v without endpoints" , svcChain , svcPortName ) , svcRules , t )
2016-09-27 02:48:21 +00:00
}
kubeSvcRules := ipt . GetRules ( string ( kubeServicesChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeSvcRules , iptablestest . Reject , svcIP , svcPort ) {
errorf ( fmt . Sprintf ( "Failed to find a %v rule for service %v with no endpoints" , iptablestest . Reject , svcPortName ) , kubeSvcRules , t )
2016-09-27 02:48:21 +00:00
}
}
func TestClusterIPEndpointsJump ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
} }
} ) ,
2017-04-14 13:28:52 +00:00
)
2017-04-03 06:21:03 +00:00
epIP := "10.180.0.1"
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestEndpoints ( svcPortName . Namespace , svcPortName . Name , func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-03 06:21:03 +00:00
IP : epIP ,
2017-02-04 02:03:45 +00:00
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2017-02-04 02:03:45 +00:00
} } ,
} }
} ) ,
2017-04-07 14:26:26 +00:00
)
2017-02-04 02:03:45 +00:00
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2016-09-27 02:48:21 +00:00
2017-04-03 06:21:03 +00:00
epStr := fmt . Sprintf ( "%s:%d" , epIP , svcPort )
2018-08-15 13:51:19 +00:00
svcChain := string ( servicePortChainName ( svcPortName . String ( ) , strings . ToLower ( string ( v1 . ProtocolTCP ) ) ) )
epChain := string ( servicePortEndpointChainName ( svcPortName . String ( ) , strings . ToLower ( string ( v1 . ProtocolTCP ) ) , epStr ) )
2016-09-27 02:48:21 +00:00
kubeSvcRules := ipt . GetRules ( string ( kubeServicesChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeSvcRules , svcChain , svcIP , svcPort ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump from KUBE-SERVICES to %v chain" , svcChain ) , kubeSvcRules , t )
}
svcRules := ipt . GetRules ( svcChain )
2017-02-04 02:03:45 +00:00
if ! hasJump ( svcRules , epChain , "" , 0 ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to jump to ep chain %v" , epChain ) , svcRules , t )
}
epRules := ipt . GetRules ( epChain )
2017-04-03 06:21:03 +00:00
if ! hasDNAT ( epRules , epStr ) {
errorf ( fmt . Sprintf ( "Endpoint chain %v lacks DNAT to %v" , epChain , epStr ) , epRules , t )
2016-09-27 02:48:21 +00:00
}
}
func TestLoadBalancer ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcLBIP := "1.2.3.4"
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . Type = "LoadBalancer"
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
NodePort : int32 ( svcNodePort ) ,
} }
2018-08-15 13:51:19 +00:00
svc . Status . LoadBalancer . Ingress = [ ] v1 . LoadBalancerIngress { {
2017-04-03 06:21:03 +00:00
IP : svcLBIP ,
} }
} ) ,
2017-04-14 13:28:52 +00:00
)
2016-09-27 02:48:21 +00:00
2017-04-03 06:21:03 +00:00
epIP := "10.180.0.1"
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestEndpoints ( svcPortName . Namespace , svcPortName . Name , func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-03 06:21:03 +00:00
IP : epIP ,
2017-02-04 02:03:45 +00:00
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2017-02-04 02:03:45 +00:00
} } ,
} }
} ) ,
2017-04-07 14:26:26 +00:00
)
2016-09-27 02:48:21 +00:00
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2016-09-27 02:48:21 +00:00
2018-08-15 13:51:19 +00:00
proto := strings . ToLower ( string ( v1 . ProtocolTCP ) )
2017-03-31 03:16:43 +00:00
fwChain := string ( serviceFirewallChainName ( svcPortName . String ( ) , proto ) )
svcChain := string ( servicePortChainName ( svcPortName . String ( ) , proto ) )
2016-09-27 02:48:21 +00:00
kubeSvcRules := ipt . GetRules ( string ( kubeServicesChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeSvcRules , fwChain , svcLBIP , svcPort ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump to firewall chain %v" , fwChain ) , kubeSvcRules , t )
}
fwRules := ipt . GetRules ( fwChain )
2017-02-04 02:03:45 +00:00
if ! hasJump ( fwRules , svcChain , "" , 0 ) || ! hasJump ( fwRules , string ( KubeMarkMasqChain ) , "" , 0 ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump from firewall chain %v to svc chain %v" , fwChain , svcChain ) , fwRules , t )
}
}
func TestNodePort ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . Type = "NodePort"
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
NodePort : int32 ( svcNodePort ) ,
} }
} ) ,
2017-04-14 13:28:52 +00:00
)
2016-09-27 02:48:21 +00:00
2017-04-03 06:21:03 +00:00
epIP := "10.180.0.1"
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestEndpoints ( svcPortName . Namespace , svcPortName . Name , func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-03 06:21:03 +00:00
IP : epIP ,
2017-02-04 02:03:45 +00:00
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2017-02-04 02:03:45 +00:00
} } ,
} }
} ) ,
2017-04-07 14:26:26 +00:00
)
2016-09-27 02:48:21 +00:00
2018-01-17 02:30:19 +00:00
itf := net . Interface { Index : 0 , MTU : 0 , Name : "lo" , HardwareAddr : nil , Flags : 0 }
addrs := [ ] net . Addr { utilproxytest . AddrStruct { Val : "127.0.0.1/16" } }
itf1 := net . Interface { Index : 1 , MTU : 0 , Name : "eth1" , HardwareAddr : nil , Flags : 0 }
addrs1 := [ ] net . Addr { utilproxytest . AddrStruct { Val : "::1/128" } }
fp . networkInterfacer . ( * utilproxytest . FakeNetwork ) . AddInterfaceAddr ( & itf , addrs )
fp . networkInterfacer . ( * utilproxytest . FakeNetwork ) . AddInterfaceAddr ( & itf1 , addrs1 )
fp . nodePortAddresses = [ ] string { }
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2016-09-27 02:48:21 +00:00
2018-08-15 13:51:19 +00:00
proto := strings . ToLower ( string ( v1 . ProtocolTCP ) )
2017-03-31 03:16:43 +00:00
svcChain := string ( servicePortChainName ( svcPortName . String ( ) , proto ) )
2016-09-27 02:48:21 +00:00
kubeNodePortRules := ipt . GetRules ( string ( kubeNodePortsChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeNodePortRules , svcChain , "" , svcNodePort ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump to svc chain %v" , svcChain ) , kubeNodePortRules , t )
}
}
2017-04-17 09:10:54 +00:00
func TestExternalIPsReject ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
svcIP := "10.20.30.41"
svcPort := 80
svcExternalIPs := "50.60.70.81"
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-17 09:10:54 +00:00
svc . Spec . Type = "ClusterIP"
svc . Spec . ClusterIP = svcIP
svc . Spec . ExternalIPs = [ ] string { svcExternalIPs }
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-17 09:10:54 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-17 09:10:54 +00:00
TargetPort : intstr . FromInt ( svcPort ) ,
} }
} ) ,
)
makeEndpointsMap ( fp )
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2017-04-17 09:10:54 +00:00
2017-11-21 17:25:27 +00:00
kubeSvcRules := ipt . GetRules ( string ( kubeExternalServicesChain ) )
2017-04-17 09:10:54 +00:00
if ! hasJump ( kubeSvcRules , iptablestest . Reject , svcExternalIPs , svcPort ) {
2018-02-17 03:09:33 +00:00
errorf ( fmt . Sprintf ( "Failed to find a %v rule for externalIP %v with no endpoints" , iptablestest . Reject , svcPortName ) , kubeSvcRules , t )
2017-04-17 09:10:54 +00:00
}
}
2017-03-20 22:54:43 +00:00
func TestNodePortReject ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . Type = "NodePort"
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
NodePort : int32 ( svcNodePort ) ,
} }
} ) ,
2017-04-14 13:28:52 +00:00
)
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp )
2017-03-20 22:54:43 +00:00
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2017-03-20 22:54:43 +00:00
2017-11-21 17:25:27 +00:00
kubeSvcRules := ipt . GetRules ( string ( kubeExternalServicesChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeSvcRules , iptablestest . Reject , svcIP , svcNodePort ) {
errorf ( fmt . Sprintf ( "Failed to find a %v rule for service %v with no endpoints" , iptablestest . Reject , svcPortName ) , kubeSvcRules , t )
2017-03-20 22:54:43 +00:00
}
}
2017-02-04 02:03:45 +00:00
func strPtr ( s string ) * string {
return & s
}
2016-09-27 02:48:21 +00:00
func TestOnlyLocalLoadBalancing ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcLBIP := "1.2.3.4"
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-11-11 02:42:07 +00:00
svcSessionAffinityTimeout := int32 ( 10800 )
2017-04-03 06:21:03 +00:00
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . Type = "LoadBalancer"
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
NodePort : int32 ( svcNodePort ) ,
} }
2018-08-15 13:51:19 +00:00
svc . Status . LoadBalancer . Ingress = [ ] v1 . LoadBalancerIngress { {
2017-04-03 06:21:03 +00:00
IP : svcLBIP ,
} }
2018-08-15 13:51:19 +00:00
svc . Spec . ExternalTrafficPolicy = v1 . ServiceExternalTrafficPolicyTypeLocal
svc . Spec . SessionAffinity = v1 . ServiceAffinityClientIP
svc . Spec . SessionAffinityConfig = & v1 . SessionAffinityConfig {
ClientIP : & v1 . ClientIPConfig { TimeoutSeconds : & svcSessionAffinityTimeout } ,
2017-11-11 02:42:07 +00:00
}
2017-04-03 06:21:03 +00:00
} ) ,
2017-04-14 13:28:52 +00:00
)
2017-04-03 06:21:03 +00:00
epIP1 := "10.180.0.1"
epIP2 := "10.180.2.1"
epStrLocal := fmt . Sprintf ( "%s:%d" , epIP1 , svcPort )
epStrNonLocal := fmt . Sprintf ( "%s:%d" , epIP2 , svcPort )
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestEndpoints ( svcPortName . Namespace , svcPortName . Name , func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-03 06:21:03 +00:00
IP : epIP1 ,
2017-02-04 02:03:45 +00:00
NodeName : nil ,
} , {
2017-04-03 06:21:03 +00:00
IP : epIP2 ,
2017-02-04 02:03:45 +00:00
NodeName : strPtr ( testHostname ) ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2017-02-04 02:03:45 +00:00
} } ,
} }
} ) ,
2017-04-07 14:26:26 +00:00
)
2017-02-04 02:03:45 +00:00
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2016-09-27 02:48:21 +00:00
2018-08-15 13:51:19 +00:00
proto := strings . ToLower ( string ( v1 . ProtocolTCP ) )
2017-03-31 03:16:43 +00:00
fwChain := string ( serviceFirewallChainName ( svcPortName . String ( ) , proto ) )
lbChain := string ( serviceLBChainName ( svcPortName . String ( ) , proto ) )
2016-09-27 02:48:21 +00:00
2018-08-15 13:51:19 +00:00
nonLocalEpChain := string ( servicePortEndpointChainName ( svcPortName . String ( ) , strings . ToLower ( string ( v1 . ProtocolTCP ) ) , epStrLocal ) )
localEpChain := string ( servicePortEndpointChainName ( svcPortName . String ( ) , strings . ToLower ( string ( v1 . ProtocolTCP ) ) , epStrNonLocal ) )
2016-09-27 02:48:21 +00:00
kubeSvcRules := ipt . GetRules ( string ( kubeServicesChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeSvcRules , fwChain , svcLBIP , svcPort ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump to firewall chain %v" , fwChain ) , kubeSvcRules , t )
}
fwRules := ipt . GetRules ( fwChain )
2017-02-04 02:03:45 +00:00
if ! hasJump ( fwRules , lbChain , "" , 0 ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump from firewall chain %v to svc chain %v" , fwChain , lbChain ) , fwRules , t )
}
2017-02-04 02:03:45 +00:00
if hasJump ( fwRules , string ( KubeMarkMasqChain ) , "" , 0 ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Found jump from fw chain %v to MASQUERADE" , fwChain ) , fwRules , t )
}
lbRules := ipt . GetRules ( lbChain )
2017-02-04 02:03:45 +00:00
if hasJump ( lbRules , nonLocalEpChain , "" , 0 ) {
2017-04-03 06:21:03 +00:00
errorf ( fmt . Sprintf ( "Found jump from lb chain %v to non-local ep %v" , lbChain , epStrLocal ) , lbRules , t )
2016-09-27 02:48:21 +00:00
}
2017-02-04 02:03:45 +00:00
if ! hasJump ( lbRules , localEpChain , "" , 0 ) {
2017-04-03 06:21:03 +00:00
errorf ( fmt . Sprintf ( "Didn't find jump from lb chain %v to local ep %v" , lbChain , epStrNonLocal ) , lbRules , t )
2016-09-27 02:48:21 +00:00
}
2017-11-11 02:42:07 +00:00
if ! hasSessionAffinityRule ( lbRules ) {
errorf ( fmt . Sprintf ( "Didn't find session affinity rule from lb chain %v" , lbChain ) , lbRules , t )
}
2016-09-27 02:48:21 +00:00
}
2016-11-15 19:29:36 +00:00
func TestOnlyLocalNodePortsNoClusterCIDR ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
// set cluster CIDR to empty before test
fp . clusterCIDR = ""
onlyLocalNodePorts ( t , fp , ipt )
}
2016-09-27 02:48:21 +00:00
func TestOnlyLocalNodePorts ( t * testing . T ) {
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2016-11-15 19:29:36 +00:00
onlyLocalNodePorts ( t , fp , ipt )
}
func onlyLocalNodePorts ( t * testing . T , fp * Proxier , ipt * iptablestest . FakeIPTables ) {
shouldLBTOSVCRuleExist := len ( fp . clusterCIDR ) > 0
2017-04-03 06:21:03 +00:00
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcPortName := proxy . ServicePortName {
NamespacedName : makeNSN ( "ns1" , "svc1" ) ,
Port : "p80" ,
}
2017-04-18 12:51:14 +00:00
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( svcPortName . Namespace , svcPortName . Name , func ( svc * v1 . Service ) {
2017-04-03 06:21:03 +00:00
svc . Spec . Type = "NodePort"
svc . Spec . ClusterIP = svcIP
2018-08-15 13:51:19 +00:00
svc . Spec . Ports = [ ] v1 . ServicePort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2018-08-15 13:51:19 +00:00
Protocol : v1 . ProtocolTCP ,
2017-04-03 06:21:03 +00:00
NodePort : int32 ( svcNodePort ) ,
} }
2018-08-15 13:51:19 +00:00
svc . Spec . ExternalTrafficPolicy = v1 . ServiceExternalTrafficPolicyTypeLocal
2017-04-03 06:21:03 +00:00
} ) ,
2017-04-14 13:28:52 +00:00
)
2017-04-03 06:21:03 +00:00
epIP1 := "10.180.0.1"
epIP2 := "10.180.2.1"
epStrLocal := fmt . Sprintf ( "%s:%d" , epIP1 , svcPort )
epStrNonLocal := fmt . Sprintf ( "%s:%d" , epIP2 , svcPort )
2017-04-11 07:59:31 +00:00
makeEndpointsMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestEndpoints ( svcPortName . Namespace , svcPortName . Name , func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-03 06:21:03 +00:00
IP : epIP1 ,
2017-02-04 02:03:45 +00:00
NodeName : nil ,
} , {
2017-04-03 06:21:03 +00:00
IP : epIP2 ,
2017-02-04 02:03:45 +00:00
NodeName : strPtr ( testHostname ) ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-03 06:21:03 +00:00
Name : svcPortName . Port ,
Port : int32 ( svcPort ) ,
2017-02-04 02:03:45 +00:00
} } ,
} }
} ) ,
2017-04-07 14:26:26 +00:00
)
2017-02-04 02:03:45 +00:00
2018-01-17 02:30:19 +00:00
itf := net . Interface { Index : 0 , MTU : 0 , Name : "eth0" , HardwareAddr : nil , Flags : 0 }
addrs := [ ] net . Addr { utilproxytest . AddrStruct { Val : "10.20.30.51/24" } }
fp . networkInterfacer . ( * utilproxytest . FakeNetwork ) . AddInterfaceAddr ( & itf , addrs )
fp . nodePortAddresses = [ ] string { "10.20.30.0/24" }
2017-05-19 06:44:44 +00:00
fp . syncProxyRules ( )
2016-09-27 02:48:21 +00:00
2018-08-15 13:51:19 +00:00
proto := strings . ToLower ( string ( v1 . ProtocolTCP ) )
2017-03-31 03:16:43 +00:00
lbChain := string ( serviceLBChainName ( svcPortName . String ( ) , proto ) )
2016-09-27 02:48:21 +00:00
2017-03-31 03:16:43 +00:00
nonLocalEpChain := string ( servicePortEndpointChainName ( svcPortName . String ( ) , proto , epStrLocal ) )
localEpChain := string ( servicePortEndpointChainName ( svcPortName . String ( ) , proto , epStrNonLocal ) )
2016-09-27 02:48:21 +00:00
kubeNodePortRules := ipt . GetRules ( string ( kubeNodePortsChain ) )
2017-04-03 06:21:03 +00:00
if ! hasJump ( kubeNodePortRules , lbChain , "" , svcNodePort ) {
2016-09-27 02:48:21 +00:00
errorf ( fmt . Sprintf ( "Failed to find jump to lb chain %v" , lbChain ) , kubeNodePortRules , t )
}
2018-01-08 02:44:47 +00:00
if ! hasJump ( kubeNodePortRules , string ( KubeMarkMasqChain ) , "" , svcNodePort ) {
errorf ( fmt . Sprintf ( "Failed to find jump to %s chain for destination IP %d" , KubeMarkMasqChain , svcNodePort ) , kubeNodePortRules , t )
}
2018-01-17 02:30:19 +00:00
kubeServiceRules := ipt . GetRules ( string ( kubeServicesChain ) )
if ! hasJump ( kubeServiceRules , string ( kubeNodePortsChain ) , "10.20.30.51" , 0 ) {
errorf ( fmt . Sprintf ( "Failed to find jump to KUBE-NODEPORTS chain %v" , string ( kubeNodePortsChain ) ) , kubeServiceRules , t )
}
2017-03-31 03:16:43 +00:00
svcChain := string ( servicePortChainName ( svcPortName . String ( ) , proto ) )
2016-09-27 02:48:21 +00:00
lbRules := ipt . GetRules ( lbChain )
2017-02-04 02:03:45 +00:00
if hasJump ( lbRules , nonLocalEpChain , "" , 0 ) {
2017-04-03 06:21:03 +00:00
errorf ( fmt . Sprintf ( "Found jump from lb chain %v to non-local ep %v" , lbChain , epStrLocal ) , lbRules , t )
2016-09-27 02:48:21 +00:00
}
2017-02-04 02:03:45 +00:00
if hasJump ( lbRules , svcChain , "" , 0 ) != shouldLBTOSVCRuleExist {
2016-11-15 19:29:36 +00:00
prefix := "Did not find "
if ! shouldLBTOSVCRuleExist {
prefix = "Found "
}
errorf ( fmt . Sprintf ( "%s jump from lb chain %v to svc %v" , prefix , lbChain , svcChain ) , lbRules , t )
}
2017-02-04 02:03:45 +00:00
if ! hasJump ( lbRules , localEpChain , "" , 0 ) {
2017-04-03 06:21:03 +00:00
errorf ( fmt . Sprintf ( "Didn't find jump from lb chain %v to local ep %v" , lbChain , epStrLocal ) , lbRules , t )
2016-09-27 02:48:21 +00:00
}
}
2018-08-15 13:51:19 +00:00
func makeTestService ( namespace , name string , svcFunc func ( * v1 . Service ) ) * v1 . Service {
svc := & v1 . Service {
2017-01-17 03:38:19 +00:00
ObjectMeta : metav1 . ObjectMeta {
2017-04-03 06:21:03 +00:00
Name : name ,
Namespace : namespace ,
Annotations : map [ string ] string { } ,
2016-12-19 23:08:24 +00:00
} ,
2018-08-15 13:51:19 +00:00
Spec : v1 . ServiceSpec { } ,
Status : v1 . ServiceStatus { } ,
2016-12-19 23:08:24 +00:00
}
2017-04-01 04:48:39 +00:00
svcFunc ( svc )
2016-12-19 23:08:24 +00:00
return svc
}
2018-08-15 13:51:19 +00:00
func addTestPort ( array [ ] v1 . ServicePort , name string , protocol v1 . Protocol , port , nodeport int32 , targetPort int ) [ ] v1 . ServicePort {
svcPort := v1 . ServicePort {
2016-12-19 23:08:24 +00:00
Name : name ,
Protocol : protocol ,
Port : port ,
NodePort : nodeport ,
TargetPort : intstr . FromInt ( targetPort ) ,
}
return append ( array , svcPort )
}
func TestBuildServiceMapAddRemove ( t * testing . T ) {
2017-04-18 12:51:14 +00:00
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2018-08-15 13:51:19 +00:00
services := [ ] * v1 . Service {
makeTestService ( "somewhere-else" , "cluster-ip" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeClusterIP
2016-12-19 23:08:24 +00:00
svc . Spec . ClusterIP = "172.16.55.4"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "something" , "UDP" , 1234 , 4321 , 0 )
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "somethingelse" , "UDP" , 1235 , 5321 , 0 )
2018-06-11 11:25:18 +00:00
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "sctpport" , "SCTP" , 1236 , 6321 , 0 )
2016-12-19 23:08:24 +00:00
} ) ,
2018-08-15 13:51:19 +00:00
makeTestService ( "somewhere-else" , "node-port" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeNodePort
2016-12-19 23:08:24 +00:00
svc . Spec . ClusterIP = "172.16.55.10"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "blahblah" , "UDP" , 345 , 678 , 0 )
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "moreblahblah" , "TCP" , 344 , 677 , 0 )
2018-06-11 11:25:18 +00:00
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "muchmoreblah" , "SCTP" , 343 , 676 , 0 )
2016-12-19 23:08:24 +00:00
} ) ,
2018-08-15 13:51:19 +00:00
makeTestService ( "somewhere" , "load-balancer" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeLoadBalancer
2016-12-19 23:08:24 +00:00
svc . Spec . ClusterIP = "172.16.55.11"
svc . Spec . LoadBalancerIP = "5.6.7.8"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "foobar" , "UDP" , 8675 , 30061 , 7000 )
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "baz" , "UDP" , 8676 , 30062 , 7001 )
2018-08-15 13:51:19 +00:00
svc . Status . LoadBalancer = v1 . LoadBalancerStatus {
Ingress : [ ] v1 . LoadBalancerIngress {
2016-12-19 23:08:24 +00:00
{ IP : "10.1.2.4" } ,
} ,
}
} ) ,
2018-08-15 13:51:19 +00:00
makeTestService ( "somewhere" , "only-local-load-balancer" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeLoadBalancer
2016-12-19 23:08:24 +00:00
svc . Spec . ClusterIP = "172.16.55.12"
svc . Spec . LoadBalancerIP = "5.6.7.8"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "foobar2" , "UDP" , 8677 , 30063 , 7002 )
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "baz" , "UDP" , 8678 , 30064 , 7003 )
2018-08-15 13:51:19 +00:00
svc . Status . LoadBalancer = v1 . LoadBalancerStatus {
Ingress : [ ] v1 . LoadBalancerIngress {
2016-12-19 23:08:24 +00:00
{ IP : "10.1.2.3" } ,
} ,
}
2018-08-15 13:51:19 +00:00
svc . Spec . ExternalTrafficPolicy = v1 . ServiceExternalTrafficPolicyTypeLocal
2017-08-04 08:50:35 +00:00
svc . Spec . HealthCheckNodePort = 345
2016-12-19 23:08:24 +00:00
} ) ,
2017-04-18 12:51:14 +00:00
}
2016-12-19 23:08:24 +00:00
2017-04-18 12:51:14 +00:00
for i := range services {
fp . OnServiceAdd ( services [ i ] )
}
2017-12-10 07:12:23 +00:00
result := proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2018-06-11 11:25:18 +00:00
if len ( fp . serviceMap ) != 10 {
t . Errorf ( "expected service map length 10, got %v" , fp . serviceMap )
2016-12-19 23:08:24 +00:00
}
// The only-local-loadbalancer ones get added
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 1 {
t . Errorf ( "expected 1 healthcheck port, got %v" , result . HCServiceNodePorts )
2016-12-19 23:08:24 +00:00
} else {
2017-04-02 04:14:30 +00:00
nsn := makeNSN ( "somewhere" , "only-local-load-balancer" )
2017-12-10 07:12:23 +00:00
if port , found := result . HCServiceNodePorts [ nsn ] ; ! found || port != 345 {
t . Errorf ( "expected healthcheck port [%q]=345: got %v" , nsn , result . HCServiceNodePorts )
2016-12-19 23:08:24 +00:00
}
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
2016-12-19 23:08:24 +00:00
// Services only added, so nothing stale yet
2017-12-10 07:12:23 +00:00
t . Errorf ( "expected stale UDP services length 0, got %d" , len ( result . UDPStaleClusterIP ) )
2016-12-19 23:08:24 +00:00
}
// Remove some stuff
2017-04-18 12:51:14 +00:00
// oneService is a modification of services[0] with removed first port.
2018-08-15 13:51:19 +00:00
oneService := makeTestService ( "somewhere-else" , "cluster-ip" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeClusterIP
2017-04-18 12:51:14 +00:00
svc . Spec . ClusterIP = "172.16.55.4"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "somethingelse" , "UDP" , 1235 , 5321 , 0 )
} )
fp . OnServiceUpdate ( services [ 0 ] , oneService )
fp . OnServiceDelete ( services [ 1 ] )
fp . OnServiceDelete ( services [ 2 ] )
fp . OnServiceDelete ( services [ 3 ] )
2017-12-10 07:12:23 +00:00
result = proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 1 {
t . Errorf ( "expected service map length 1, got %v" , fp . serviceMap )
2016-12-19 23:08:24 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 0 {
t . Errorf ( "expected 0 healthcheck ports, got %v" , result . HCServiceNodePorts )
2016-12-19 23:08:24 +00:00
}
// All services but one were deleted. While you'd expect only the ClusterIPs
// from the three deleted services here, we still have the ClusterIP for
// the not-deleted service, because one of it's ServicePorts was deleted.
expectedStaleUDPServices := [ ] string { "172.16.55.10" , "172.16.55.4" , "172.16.55.11" , "172.16.55.12" }
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != len ( expectedStaleUDPServices ) {
t . Errorf ( "expected stale UDP services length %d, got %v" , len ( expectedStaleUDPServices ) , result . UDPStaleClusterIP . UnsortedList ( ) )
2016-12-19 23:08:24 +00:00
}
for _ , ip := range expectedStaleUDPServices {
2017-12-10 07:12:23 +00:00
if ! result . UDPStaleClusterIP . Has ( ip ) {
2016-12-19 23:08:24 +00:00
t . Errorf ( "expected stale UDP service service %s" , ip )
}
}
}
func TestBuildServiceMapServiceHeadless ( t * testing . T ) {
2017-04-18 12:51:14 +00:00
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( "somewhere-else" , "headless" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeClusterIP
svc . Spec . ClusterIP = v1 . ClusterIPNone
2016-12-19 23:08:24 +00:00
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "rpc" , "UDP" , 1234 , 0 , 0 )
} ) ,
2018-08-15 13:51:19 +00:00
makeTestService ( "somewhere-else" , "headless-without-port" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeClusterIP
svc . Spec . ClusterIP = v1 . ClusterIPNone
2017-06-09 15:22:37 +00:00
} ) ,
2017-04-14 13:28:52 +00:00
)
2016-12-19 23:08:24 +00:00
// Headless service should be ignored
2017-12-10 07:12:23 +00:00
result := proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 0 {
t . Errorf ( "expected service map length 0, got %d" , len ( fp . serviceMap ) )
2016-12-19 23:08:24 +00:00
}
// No proxied services, so no healthchecks
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 0 {
t . Errorf ( "expected healthcheck ports length 0, got %d" , len ( result . HCServiceNodePorts ) )
2016-12-19 23:08:24 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
t . Errorf ( "expected stale UDP services length 0, got %d" , len ( result . UDPStaleClusterIP ) )
2016-12-19 23:08:24 +00:00
}
}
2016-12-19 23:12:32 +00:00
func TestBuildServiceMapServiceTypeExternalName ( t * testing . T ) {
2017-04-18 12:51:14 +00:00
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
makeServiceMap ( fp ,
2018-08-15 13:51:19 +00:00
makeTestService ( "somewhere-else" , "external-name" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeExternalName
2016-12-19 23:12:32 +00:00
svc . Spec . ClusterIP = "172.16.55.4" // Should be ignored
svc . Spec . ExternalName = "foo2.bar.com"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "blah" , "UDP" , 1235 , 5321 , 0 )
} ) ,
2017-04-14 13:28:52 +00:00
)
2016-12-19 23:12:32 +00:00
2017-12-10 07:12:23 +00:00
result := proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 0 {
t . Errorf ( "expected service map length 0, got %v" , fp . serviceMap )
2016-12-19 23:12:32 +00:00
}
// No proxied services, so no healthchecks
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 0 {
t . Errorf ( "expected healthcheck ports length 0, got %v" , result . HCServiceNodePorts )
2016-12-19 23:12:32 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
t . Errorf ( "expected stale UDP services length 0, got %v" , result . UDPStaleClusterIP )
2016-12-19 23:12:32 +00:00
}
}
2016-12-20 18:24:43 +00:00
func TestBuildServiceMapServiceUpdate ( t * testing . T ) {
2017-04-18 12:51:14 +00:00
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
2016-12-20 18:24:43 +00:00
2018-08-15 13:51:19 +00:00
servicev1 := makeTestService ( "somewhere" , "some-service" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeClusterIP
2017-04-18 12:51:14 +00:00
svc . Spec . ClusterIP = "172.16.55.4"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "something" , "UDP" , 1234 , 4321 , 0 )
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "somethingelse" , "TCP" , 1235 , 5321 , 0 )
} )
2018-08-15 13:51:19 +00:00
servicev2 := makeTestService ( "somewhere" , "some-service" , func ( svc * v1 . Service ) {
svc . Spec . Type = v1 . ServiceTypeLoadBalancer
2017-04-18 12:51:14 +00:00
svc . Spec . ClusterIP = "172.16.55.4"
svc . Spec . LoadBalancerIP = "5.6.7.8"
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "something" , "UDP" , 1234 , 4321 , 7002 )
svc . Spec . Ports = addTestPort ( svc . Spec . Ports , "somethingelse" , "TCP" , 1235 , 5321 , 7003 )
2018-08-15 13:51:19 +00:00
svc . Status . LoadBalancer = v1 . LoadBalancerStatus {
Ingress : [ ] v1 . LoadBalancerIngress {
2017-04-18 12:51:14 +00:00
{ IP : "10.1.2.3" } ,
} ,
}
2018-08-15 13:51:19 +00:00
svc . Spec . ExternalTrafficPolicy = v1 . ServiceExternalTrafficPolicyTypeLocal
2017-08-04 08:50:35 +00:00
svc . Spec . HealthCheckNodePort = 345
2017-04-18 12:51:14 +00:00
} )
2016-12-20 18:24:43 +00:00
2017-04-18 12:51:14 +00:00
fp . OnServiceAdd ( servicev1 )
2017-12-10 07:12:23 +00:00
result := proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 2 {
t . Errorf ( "expected service map length 2, got %v" , fp . serviceMap )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 0 {
t . Errorf ( "expected healthcheck ports length 0, got %v" , result . HCServiceNodePorts )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
2016-12-20 18:24:43 +00:00
// Services only added, so nothing stale yet
2017-12-10 07:12:23 +00:00
t . Errorf ( "expected stale UDP services length 0, got %d" , len ( result . UDPStaleClusterIP ) )
2016-12-20 18:24:43 +00:00
}
// Change service to load-balancer
2017-04-18 12:51:14 +00:00
fp . OnServiceUpdate ( servicev1 , servicev2 )
2017-12-10 07:12:23 +00:00
result = proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 2 {
t . Errorf ( "expected service map length 2, got %v" , fp . serviceMap )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 1 {
t . Errorf ( "expected healthcheck ports length 1, got %v" , result . HCServiceNodePorts )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
t . Errorf ( "expected stale UDP services length 0, got %v" , result . UDPStaleClusterIP . UnsortedList ( ) )
2016-12-20 18:24:43 +00:00
}
// No change; make sure the service map stays the same and there are
// no health-check changes
2017-04-18 12:51:14 +00:00
fp . OnServiceUpdate ( servicev2 , servicev2 )
2017-12-10 07:12:23 +00:00
result = proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 2 {
t . Errorf ( "expected service map length 2, got %v" , fp . serviceMap )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 1 {
t . Errorf ( "expected healthcheck ports length 1, got %v" , result . HCServiceNodePorts )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
t . Errorf ( "expected stale UDP services length 0, got %v" , result . UDPStaleClusterIP . UnsortedList ( ) )
2016-12-20 18:24:43 +00:00
}
// And back to ClusterIP
2017-04-18 12:51:14 +00:00
fp . OnServiceUpdate ( servicev2 , servicev1 )
2017-12-10 07:12:23 +00:00
result = proxy . UpdateServiceMap ( fp . serviceMap , fp . serviceChanges )
2017-04-18 12:51:14 +00:00
if len ( fp . serviceMap ) != 2 {
t . Errorf ( "expected service map length 2, got %v" , fp . serviceMap )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . HCServiceNodePorts ) != 0 {
t . Errorf ( "expected healthcheck ports length 0, got %v" , result . HCServiceNodePorts )
2016-12-20 18:24:43 +00:00
}
2017-12-10 07:12:23 +00:00
if len ( result . UDPStaleClusterIP ) != 0 {
2016-12-20 18:24:43 +00:00
// Services only added, so nothing stale yet
2017-12-10 07:12:23 +00:00
t . Errorf ( "expected stale UDP services length 0, got %d" , len ( result . UDPStaleClusterIP ) )
2017-02-01 20:47:29 +00:00
}
}
2018-08-15 13:51:19 +00:00
func makeTestEndpoints ( namespace , name string , eptFunc func ( * v1 . Endpoints ) ) * v1 . Endpoints {
ept := & v1 . Endpoints {
2017-02-01 20:47:29 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : name ,
Namespace : namespace ,
} ,
}
2017-03-09 15:42:45 +00:00
eptFunc ( ept )
2017-02-01 20:47:29 +00:00
return ept
}
2018-08-15 13:51:19 +00:00
func makeEndpointsMap ( proxier * Proxier , allEndpoints ... * v1 . Endpoints ) {
2017-04-11 07:59:31 +00:00
for i := range allEndpoints {
proxier . OnEndpointsAdd ( allEndpoints [ i ] )
2017-04-07 14:26:26 +00:00
}
2017-04-11 07:59:31 +00:00
proxier . mu . Lock ( )
defer proxier . mu . Unlock ( )
proxier . endpointsSynced = true
2017-04-07 14:26:26 +00:00
}
2017-04-02 04:14:30 +00:00
func makeNSN ( namespace , name string ) types . NamespacedName {
return types . NamespacedName { Namespace : namespace , Name : name }
}
2017-02-01 20:47:29 +00:00
func makeServicePortName ( ns , name , port string ) proxy . ServicePortName {
return proxy . ServicePortName {
2017-04-02 04:14:30 +00:00
NamespacedName : makeNSN ( ns , name ) ,
Port : port ,
2017-02-01 20:47:29 +00:00
}
}
2018-08-15 13:51:19 +00:00
func makeServiceMap ( proxier * Proxier , allServices ... * v1 . Service ) {
2017-04-18 12:51:14 +00:00
for i := range allServices {
proxier . OnServiceAdd ( allServices [ i ] )
2017-04-14 13:28:52 +00:00
}
2017-04-18 12:51:14 +00:00
proxier . mu . Lock ( )
defer proxier . mu . Unlock ( )
proxier . servicesSynced = true
2017-04-14 13:28:52 +00:00
}
2017-12-10 07:12:23 +00:00
func compareEndpointsMaps ( t * testing . T , tci int , newMap proxy . EndpointsMap , expected map [ proxy . ServicePortName ] [ ] * endpointsInfo ) {
2017-04-11 07:59:31 +00:00
if len ( newMap ) != len ( expected ) {
t . Errorf ( "[%d] expected %d results, got %d: %v" , tci , len ( expected ) , len ( newMap ) , newMap )
}
for x := range expected {
if len ( newMap [ x ] ) != len ( expected [ x ] ) {
t . Errorf ( "[%d] expected %d endpoints for %v, got %d" , tci , len ( expected [ x ] ) , x , len ( newMap [ x ] ) )
} else {
for i := range expected [ x ] {
2017-12-10 07:12:23 +00:00
newEp , ok := newMap [ x ] [ i ] . ( * endpointsInfo )
if ! ok {
t . Errorf ( "Failed to cast endpointsInfo" )
continue
}
2018-02-17 03:09:33 +00:00
if newEp . Endpoint != expected [ x ] [ i ] . Endpoint ||
newEp . IsLocal != expected [ x ] [ i ] . IsLocal ||
newEp . protocol != expected [ x ] [ i ] . protocol ||
newEp . chainName != expected [ x ] [ i ] . chainName {
2017-12-10 07:12:23 +00:00
t . Errorf ( "[%d] expected new[%v][%d] to be %v, got %v" , tci , x , i , expected [ x ] [ i ] , newEp )
2017-04-11 07:59:31 +00:00
}
}
}
}
}
func Test_updateEndpointsMap ( t * testing . T ) {
2017-05-15 07:55:15 +00:00
var nodeName = testHostname
2017-04-01 19:55:29 +00:00
2018-08-15 13:51:19 +00:00
emptyEndpoint := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { }
2017-07-06 22:58:01 +00:00
}
2018-08-15 13:51:19 +00:00
unnamedPort := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Port : 11 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
unnamedPortLocal := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Port : 11 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
namedPortLocal := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
namedPort := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
namedPortRenamed := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11-2" ,
Port : 11 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
namedPortRenumbered := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 22 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
namedPortsLocalNoLocal := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} , {
IP : "1.1.1.2" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} , {
Name : "p12" ,
Port : 12 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
multipleSubsets := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.2" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p12" ,
Port : 12 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
multipleSubsetsWithLocal := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.2" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p12" ,
Port : 12 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
multipleSubsetsMultiplePortsLocal := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} , {
Name : "p12" ,
Port : 12 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.3" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p13" ,
Port : 13 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
multipleSubsetsIPsPorts1 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} , {
IP : "1.1.1.2" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} , {
Name : "p12" ,
Port : 12 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.3" ,
} , {
IP : "1.1.1.4" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p13" ,
Port : 13 ,
} , {
Name : "p14" ,
Port : 14 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
multipleSubsetsIPsPorts2 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "2.2.2.1" ,
} , {
IP : "2.2.2.2" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p21" ,
Port : 21 ,
} , {
Name : "p22" ,
Port : 22 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
complexBefore1 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
complexBefore2 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "2.2.2.2" ,
NodeName : & nodeName ,
} , {
IP : "2.2.2.22" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p22" ,
Port : 22 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "2.2.2.3" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p23" ,
Port : 23 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
complexBefore4 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "4.4.4.4" ,
NodeName : & nodeName ,
} , {
IP : "4.4.4.5" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p44" ,
Port : 44 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "4.4.4.6" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p45" ,
Port : 45 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
complexAfter1 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.1" ,
} , {
IP : "1.1.1.11" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p11" ,
Port : 11 ,
} } ,
} , {
2018-08-15 13:51:19 +00:00
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "1.1.1.2" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p12" ,
Port : 12 ,
} , {
Name : "p122" ,
Port : 122 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
complexAfter3 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "3.3.3.3" ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p33" ,
Port : 33 ,
} } ,
} }
}
2018-08-15 13:51:19 +00:00
complexAfter4 := func ( ept * v1 . Endpoints ) {
ept . Subsets = [ ] v1 . EndpointSubset { {
Addresses : [ ] v1 . EndpointAddress { {
2017-04-11 07:59:31 +00:00
IP : "4.4.4.4" ,
NodeName : & nodeName ,
} } ,
2018-08-15 13:51:19 +00:00
Ports : [ ] v1 . EndpointPort { {
2017-04-11 07:59:31 +00:00
Name : "p44" ,
Port : 44 ,
} } ,
} }
}
2017-02-04 00:05:09 +00:00
testCases := [ ] struct {
2017-04-11 07:59:31 +00:00
// previousEndpoints and currentEndpoints are used to call appropriate
// handlers OnEndpoints* (based on whether corresponding values are nil
// or non-nil) and must be of equal length.
2018-08-15 13:51:19 +00:00
previousEndpoints [ ] * v1 . Endpoints
currentEndpoints [ ] * v1 . Endpoints
2017-07-06 22:58:01 +00:00
oldEndpoints map [ proxy . ServicePortName ] [ ] * endpointsInfo
expectedResult map [ proxy . ServicePortName ] [ ] * endpointsInfo
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints [ ] proxy . ServiceEndpoint
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames map [ proxy . ServicePortName ] bool
expectedHealthchecks map [ types . NamespacedName ] int
2017-02-04 00:05:09 +00:00
} { {
// Case[0]: nothing
2017-07-06 22:58:01 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo { } ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo { } ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
// Case[1]: no change, unnamed port
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , unnamedPort ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , unnamedPort ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
2017-04-01 19:55:29 +00:00
// Case[2]: no change, named port, local
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPortLocal ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPortLocal ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns1" , "ep1" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-02-04 00:05:09 +00:00
} , {
// Case[3]: no change, multiple subsets
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsets ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsets ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
2017-04-01 19:55:29 +00:00
// Case[4]: no change, multiple subsets, multiple ports, local
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsetsMultiplePortsLocal ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsetsMultiplePortsLocal ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p13" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.3:13" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p13" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.3:13" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns1" , "ep1" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-02-04 00:05:09 +00:00
} , {
// Case[5]: no change, multiple endpoints, subsets, IPs, and ports
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsetsIPsPorts1 ) ,
makeTestEndpoints ( "ns2" , "ep2" , multipleSubsetsIPsPorts2 ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsetsIPsPorts1 ) ,
makeTestEndpoints ( "ns2" , "ep2" , multipleSubsetsIPsPorts2 ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:12" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p13" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.3:13" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.4:13" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p14" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.3:14" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.4:14" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns2" , "ep2" , "p21" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.1:21" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.2:21" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns2" , "ep2" , "p22" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.1:22" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.2:22" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:12" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p13" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.3:13" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.4:13" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p14" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.3:14" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.4:14" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns2" , "ep2" , "p21" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.1:21" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.2:21" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns2" , "ep2" , "p22" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.1:22" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.2:22" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns1" , "ep1" ) : 2 ,
makeNSN ( "ns2" , "ep2" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-02-04 00:05:09 +00:00
} , {
// Case[6]: add an Endpoints
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
nil ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , unnamedPortLocal ) ,
} ,
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo { } ,
2017-02-04 00:05:09 +00:00
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool {
makeServicePortName ( "ns1" , "ep1" , "" ) : true ,
} ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns1" , "ep1" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-02-04 00:05:09 +00:00
} , {
// Case[7]: remove an Endpoints
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , unnamedPortLocal ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
nil ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo { } ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { {
Endpoint : "1.1.1.1:11" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "" ) ,
2017-02-04 00:05:09 +00:00
} } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
// Case[8]: add an IP and port
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPort ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPortsLocalNoLocal ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:12" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool {
makeServicePortName ( "ns1" , "ep1" , "p12" ) : true ,
} ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns1" , "ep1" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-02-04 00:05:09 +00:00
} , {
// Case[9]: remove an IP and port
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPortsLocalNoLocal ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPort ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:11" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:12" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { {
Endpoint : "1.1.1.2:11" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "p11" ) ,
2017-02-04 00:05:09 +00:00
} , {
2017-12-10 07:12:23 +00:00
Endpoint : "1.1.1.1:12" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "p12" ) ,
2017-02-04 00:05:09 +00:00
} , {
2017-12-10 07:12:23 +00:00
Endpoint : "1.1.1.2:12" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "p12" ) ,
2017-02-04 00:05:09 +00:00
} } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
// Case[10]: add a subset
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPort ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsetsWithLocal ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
2017-04-11 07:59:31 +00:00
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool {
makeServicePortName ( "ns1" , "ep1" , "p12" ) : true ,
} ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns1" , "ep1" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-02-04 00:05:09 +00:00
} , {
// Case[11]: remove a subset
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , multipleSubsets ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPort ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
2017-04-11 07:59:31 +00:00
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { {
Endpoint : "1.1.1.2:12" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "p12" ) ,
2017-02-04 00:05:09 +00:00
} } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
// Case[12]: rename a port
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPort ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPortRenamed ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11-2" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { {
Endpoint : "1.1.1.1:11" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "p11" ) ,
2017-02-04 00:05:09 +00:00
} } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool {
makeServicePortName ( "ns1" , "ep1" , "p11-2" ) : true ,
} ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
// Case[13]: renumber a port
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPort ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , namedPortRenumbered ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:22" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { {
Endpoint : "1.1.1.1:11" ,
ServicePortName : makeServicePortName ( "ns1" , "ep1" , "p11" ) ,
2017-02-04 00:05:09 +00:00
} } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool { } ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
2017-02-04 00:05:09 +00:00
} , {
// Case[14]: complex add and remove
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , complexBefore1 ) ,
makeTestEndpoints ( "ns2" , "ep2" , complexBefore2 ) ,
nil ,
makeTestEndpoints ( "ns4" , "ep4" , complexBefore4 ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-04-11 07:59:31 +00:00
makeTestEndpoints ( "ns1" , "ep1" , complexAfter1 ) ,
nil ,
makeTestEndpoints ( "ns3" , "ep3" , complexAfter3 ) ,
makeTestEndpoints ( "ns4" , "ep4" , complexAfter4 ) ,
} ,
2017-02-04 00:05:09 +00:00
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns2" , "ep2" , "p22" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.2:22" , IsLocal : true } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.22:22" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns2" , "ep2" , "p23" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "2.2.2.3:23" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns4" , "ep4" , "p44" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "4.4.4.4:44" , IsLocal : true } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "4.4.4.5:44" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns4" , "ep4" , "p45" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "4.4.4.6:45" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "p11" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.11:11" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p12" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:12" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns1" , "ep1" , "p122" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.2:122" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns3" , "ep3" , "p33" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "3.3.3.3:33" , IsLocal : false } } ,
2017-02-04 00:05:09 +00:00
} ,
makeServicePortName ( "ns4" , "ep4" , "p44" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "4.4.4.4:44" , IsLocal : true } } ,
2017-02-04 00:05:09 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { {
Endpoint : "2.2.2.2:22" ,
ServicePortName : makeServicePortName ( "ns2" , "ep2" , "p22" ) ,
2017-02-04 00:05:09 +00:00
} , {
2017-12-10 07:12:23 +00:00
Endpoint : "2.2.2.22:22" ,
ServicePortName : makeServicePortName ( "ns2" , "ep2" , "p22" ) ,
2017-02-04 00:05:09 +00:00
} , {
2017-12-10 07:12:23 +00:00
Endpoint : "2.2.2.3:23" ,
ServicePortName : makeServicePortName ( "ns2" , "ep2" , "p23" ) ,
2017-02-04 00:05:09 +00:00
} , {
2017-12-10 07:12:23 +00:00
Endpoint : "4.4.4.5:44" ,
ServicePortName : makeServicePortName ( "ns4" , "ep4" , "p44" ) ,
2017-02-04 00:05:09 +00:00
} , {
2017-12-10 07:12:23 +00:00
Endpoint : "4.4.4.6:45" ,
ServicePortName : makeServicePortName ( "ns4" , "ep4" , "p45" ) ,
2017-02-04 00:05:09 +00:00
} } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool {
makeServicePortName ( "ns1" , "ep1" , "p12" ) : true ,
makeServicePortName ( "ns1" , "ep1" , "p122" ) : true ,
makeServicePortName ( "ns3" , "ep3" , "p33" ) : true ,
} ,
2017-04-02 04:14:30 +00:00
expectedHealthchecks : map [ types . NamespacedName ] int {
makeNSN ( "ns4" , "ep4" ) : 1 ,
2017-04-01 19:55:29 +00:00
} ,
2017-07-06 22:58:01 +00:00
} , {
// Case[15]: change from 0 endpoint address to 1 unnamed port
2018-08-15 13:51:19 +00:00
previousEndpoints : [ ] * v1 . Endpoints {
2017-07-06 22:58:01 +00:00
makeTestEndpoints ( "ns1" , "ep1" , emptyEndpoint ) ,
} ,
2018-08-15 13:51:19 +00:00
currentEndpoints : [ ] * v1 . Endpoints {
2017-07-06 22:58:01 +00:00
makeTestEndpoints ( "ns1" , "ep1" , unnamedPort ) ,
} ,
oldEndpoints : map [ proxy . ServicePortName ] [ ] * endpointsInfo { } ,
expectedResult : map [ proxy . ServicePortName ] [ ] * endpointsInfo {
makeServicePortName ( "ns1" , "ep1" , "" ) : {
2018-02-24 21:32:55 +00:00
{ BaseEndpointInfo : & proxy . BaseEndpointInfo { Endpoint : "1.1.1.1:11" , IsLocal : false } } ,
2017-07-06 22:58:01 +00:00
} ,
} ,
2017-12-10 07:12:23 +00:00
expectedStaleEndpoints : [ ] proxy . ServiceEndpoint { } ,
2017-07-06 22:58:01 +00:00
expectedStaleServiceNames : map [ proxy . ServicePortName ] bool {
makeServicePortName ( "ns1" , "ep1" , "" ) : true ,
} ,
expectedHealthchecks : map [ types . NamespacedName ] int { } ,
} ,
}
2017-02-04 00:05:09 +00:00
for tci , tc := range testCases {
2017-04-11 07:59:31 +00:00
ipt := iptablestest . NewFake ( )
fp := NewFakeProxier ( ipt )
fp . hostname = nodeName
// First check that after adding all previous versions of endpoints,
// the fp.oldEndpoints is as we expect.
for i := range tc . previousEndpoints {
if tc . previousEndpoints [ i ] != nil {
fp . OnEndpointsAdd ( tc . previousEndpoints [ i ] )
}
2017-02-04 00:05:09 +00:00
}
2017-12-10 07:12:23 +00:00
proxy . UpdateEndpointsMap ( fp . endpointsMap , fp . endpointsChanges )
2017-04-11 07:59:31 +00:00
compareEndpointsMaps ( t , tci , fp . endpointsMap , tc . oldEndpoints )
// Now let's call appropriate handlers to get to state we want to be.
if len ( tc . previousEndpoints ) != len ( tc . currentEndpoints ) {
t . Fatalf ( "[%d] different lengths of previous and current endpoints" , tci )
continue
}
for i := range tc . previousEndpoints {
prev , curr := tc . previousEndpoints [ i ] , tc . currentEndpoints [ i ]
switch {
case prev == nil :
fp . OnEndpointsAdd ( curr )
case curr == nil :
fp . OnEndpointsDelete ( prev )
default :
fp . OnEndpointsUpdate ( prev , curr )
2017-02-04 00:05:09 +00:00
}
}
2017-12-10 07:12:23 +00:00
result := proxy . UpdateEndpointsMap ( fp . endpointsMap , fp . endpointsChanges )
2017-04-11 07:59:31 +00:00
newMap := fp . endpointsMap
compareEndpointsMaps ( t , tci , newMap , tc . expectedResult )
2017-12-10 07:12:23 +00:00
if len ( result . StaleEndpoints ) != len ( tc . expectedStaleEndpoints ) {
t . Errorf ( "[%d] expected %d staleEndpoints, got %d: %v" , tci , len ( tc . expectedStaleEndpoints ) , len ( result . StaleEndpoints ) , result . StaleEndpoints )
2017-07-06 22:58:01 +00:00
}
for _ , x := range tc . expectedStaleEndpoints {
2017-12-10 07:12:23 +00:00
found := false
for _ , stale := range result . StaleEndpoints {
if stale == x {
found = true
break
}
}
if ! found {
t . Errorf ( "[%d] expected staleEndpoints[%v], but didn't find it: %v" , tci , x , result . StaleEndpoints )
2017-07-06 22:58:01 +00:00
}
}
2017-12-10 07:12:23 +00:00
if len ( result . StaleServiceNames ) != len ( tc . expectedStaleServiceNames ) {
t . Errorf ( "[%d] expected %d staleServiceNames, got %d: %v" , tci , len ( tc . expectedStaleServiceNames ) , len ( result . StaleServiceNames ) , result . StaleServiceNames )
2017-02-04 00:05:09 +00:00
}
2017-07-06 22:58:01 +00:00
for svcName := range tc . expectedStaleServiceNames {
2017-12-10 07:12:23 +00:00
found := false
for _ , stale := range result . StaleServiceNames {
if stale == svcName {
found = true
}
}
if ! found {
t . Errorf ( "[%d] expected staleServiceNames[%v], but didn't find it: %v" , tci , svcName , result . StaleServiceNames )
2017-02-04 00:05:09 +00:00
}
}
2017-12-10 07:12:23 +00:00
if ! reflect . DeepEqual ( result . HCEndpointsLocalIPSize , tc . expectedHealthchecks ) {
t . Errorf ( "[%d] expected healthchecks %v, got %v" , tci , tc . expectedHealthchecks , result . HCEndpointsLocalIPSize )
2017-04-01 19:55:29 +00:00
}
2017-02-04 00:05:09 +00:00
}
}
2016-09-27 02:48:21 +00:00
// TODO(thockin): add *more* tests for syncProxyRules() or break it down further and test the pieces.