Merge pull request #96371 from andrewsykim/kube-proxy-terminating

kube-proxy: track serving/terminating conditions in endpoints cache
This commit is contained in:
Kubernetes Prow Robot 2021-01-11 18:38:25 -08:00 committed by GitHub
commit eb08f36c7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 698 additions and 420 deletions

View File

@ -49,6 +49,23 @@ type BaseEndpointInfo struct {
// IsLocal indicates whether the endpoint is running in same host as kube-proxy. // IsLocal indicates whether the endpoint is running in same host as kube-proxy.
IsLocal bool IsLocal bool
Topology map[string]string Topology map[string]string
// Ready indicates whether this endpoint is ready and NOT terminating.
// For pods, this is true if a pod has a ready status and a nil deletion timestamp.
// This is only set when watching EndpointSlices. If using Endpoints, this is always
// true since only ready endpoints are read from Endpoints.
// TODO: Ready can be inferred from Serving and Terminating below when enabled by default.
Ready bool
// Serving indiciates whether this endpoint is ready regardless of its terminating state.
// For pods this is true if it has a ready status regardless of its deletion timestamp.
// This is only set when watching EndpointSlices. If using Endpoints, this is always
// true since only ready endpoints are read from Endpoints.
Serving bool
// Terminating indicates whether this endpoint is terminating.
// For pods this is true if it has a non-nil deletion timestamp.
// This is only set when watching EndpointSlices. If using Endpoints, this is always
// false since terminating endpoints are always excluded from Endpoints.
Terminating bool
} }
var _ Endpoint = &BaseEndpointInfo{} var _ Endpoint = &BaseEndpointInfo{}
@ -63,6 +80,23 @@ func (info *BaseEndpointInfo) GetIsLocal() bool {
return info.IsLocal return info.IsLocal
} }
// IsReady returns true if an endpoint is ready and not terminating.
func (info *BaseEndpointInfo) IsReady() bool {
return info.Ready
}
// IsServing returns true if an endpoint is ready, regardless of if the
// endpoint is terminating.
func (info *BaseEndpointInfo) IsServing() bool {
return info.Serving
}
// IsTerminating retruns true if an endpoint is terminating. For pods,
// that is any pod with a deletion timestamp.
func (info *BaseEndpointInfo) IsTerminating() bool {
return info.Terminating
}
// GetTopology returns the topology information of the endpoint. // GetTopology returns the topology information of the endpoint.
func (info *BaseEndpointInfo) GetTopology() map[string]string { func (info *BaseEndpointInfo) GetTopology() map[string]string {
return info.Topology return info.Topology
@ -83,11 +117,15 @@ func (info *BaseEndpointInfo) Equal(other Endpoint) bool {
return info.String() == other.String() && info.GetIsLocal() == other.GetIsLocal() return info.String() == other.String() && info.GetIsLocal() == other.GetIsLocal()
} }
func newBaseEndpointInfo(IP string, port int, isLocal bool, topology map[string]string) *BaseEndpointInfo { func newBaseEndpointInfo(IP string, port int, isLocal bool, topology map[string]string,
ready, serving, terminating bool) *BaseEndpointInfo {
return &BaseEndpointInfo{ return &BaseEndpointInfo{
Endpoint: net.JoinHostPort(IP, strconv.Itoa(port)), Endpoint: net.JoinHostPort(IP, strconv.Itoa(port)),
IsLocal: isLocal, IsLocal: isLocal,
Topology: topology, Topology: topology,
Ready: ready,
Serving: serving,
Terminating: terminating,
} }
} }
@ -331,7 +369,7 @@ func (em EndpointsMap) Update(changes *EndpointChangeTracker) (result UpdateEndp
// TODO: If this will appear to be computationally expensive, consider // TODO: If this will appear to be computationally expensive, consider
// computing this incrementally similarly to endpointsMap. // computing this incrementally similarly to endpointsMap.
result.HCEndpointsLocalIPSize = make(map[types.NamespacedName]int) result.HCEndpointsLocalIPSize = make(map[types.NamespacedName]int)
localIPs := em.getLocalEndpointIPs() localIPs := em.getLocalReadyEndpointIPs()
for nsn, ips := range localIPs { for nsn, ips := range localIPs {
result.HCEndpointsLocalIPSize[nsn] = len(ips) result.HCEndpointsLocalIPSize[nsn] = len(ips)
} }
@ -383,8 +421,14 @@ func (ect *EndpointChangeTracker) endpointsToEndpointsMap(endpoints *v1.Endpoint
continue continue
} }
// it is safe to assume that any address in endpoints.subsets[*].addresses is
// ready and NOT terminating
isReady := true
isServing := true
isTerminating := false
isLocal := addr.NodeName != nil && *addr.NodeName == ect.hostname isLocal := addr.NodeName != nil && *addr.NodeName == ect.hostname
baseEndpointInfo := newBaseEndpointInfo(addr.IP, int(port.Port), isLocal, nil)
baseEndpointInfo := newBaseEndpointInfo(addr.IP, int(port.Port), isLocal, nil, isReady, isServing, isTerminating)
if ect.makeEndpointInfo != nil { if ect.makeEndpointInfo != nil {
endpointsMap[svcPortName] = append(endpointsMap[svcPortName], ect.makeEndpointInfo(baseEndpointInfo)) endpointsMap[svcPortName] = append(endpointsMap[svcPortName], ect.makeEndpointInfo(baseEndpointInfo))
} else { } else {
@ -437,10 +481,16 @@ func (em EndpointsMap) unmerge(other EndpointsMap) {
} }
// GetLocalEndpointIPs returns endpoints IPs if given endpoint is local - local means the endpoint is running in same host as kube-proxy. // GetLocalEndpointIPs returns endpoints IPs if given endpoint is local - local means the endpoint is running in same host as kube-proxy.
func (em EndpointsMap) getLocalEndpointIPs() map[types.NamespacedName]sets.String { func (em EndpointsMap) getLocalReadyEndpointIPs() map[types.NamespacedName]sets.String {
localIPs := make(map[types.NamespacedName]sets.String) localIPs := make(map[types.NamespacedName]sets.String)
for svcPortName, epList := range em { for svcPortName, epList := range em {
for _, ep := range epList { for _, ep := range epList {
// Only add ready endpoints for health checking. Terminating endpoints may still serve traffic
// but the health check signal should fail if there are only terminating endpoints on a node.
if !ep.IsReady() {
continue
}
if ep.GetIsLocal() { if ep.GetIsLocal() {
nsn := svcPortName.NamespacedName nsn := svcPortName.NamespacedName
if localIPs[nsn] == nil { if localIPs[nsn] == nil {

View File

@ -55,7 +55,7 @@ func TestGetLocalEndpointIPs(t *testing.T) {
// Case[1]: unnamed port // Case[1]: unnamed port
endpointsMap: EndpointsMap{ endpointsMap: EndpointsMap{
makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}, &BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expected: map[types.NamespacedName]sets.String{}, expected: map[types.NamespacedName]sets.String{},
@ -63,7 +63,7 @@ func TestGetLocalEndpointIPs(t *testing.T) {
// Case[2]: unnamed port local // Case[2]: unnamed port local
endpointsMap: EndpointsMap{ endpointsMap: EndpointsMap{
makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}, &BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expected: map[types.NamespacedName]sets.String{ expected: map[types.NamespacedName]sets.String{
@ -73,12 +73,12 @@ func TestGetLocalEndpointIPs(t *testing.T) {
// Case[3]: named local and non-local ports for the same IP. // Case[3]: named local and non-local ports for the same IP.
endpointsMap: EndpointsMap{ endpointsMap: EndpointsMap{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns1", "ep1", "p11", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}, &BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true}, &BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns1", "ep1", "p12", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false}, &BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true}, &BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expected: map[types.NamespacedName]sets.String{ expected: map[types.NamespacedName]sets.String{
@ -88,32 +88,57 @@ func TestGetLocalEndpointIPs(t *testing.T) {
// Case[4]: named local and non-local ports for different IPs. // Case[4]: named local and non-local ports for different IPs.
endpointsMap: EndpointsMap{ endpointsMap: EndpointsMap{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns1", "ep1", "p11", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}, &BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns2", "ep2", "p22", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true}, &BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "2.2.2.22:22", IsLocal: true}, &BaseEndpointInfo{Endpoint: "2.2.2.22:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p23", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns2", "ep2", "p23", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "2.2.2.3:23", IsLocal: true}, &BaseEndpointInfo{Endpoint: "2.2.2.3:23", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns4", "ep4", "p44", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true}, &BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "4.4.4.5:44", IsLocal: false}, &BaseEndpointInfo{Endpoint: "4.4.4.5:44", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p45", v1.ProtocolTCP): []Endpoint{ makeServicePortName("ns4", "ep4", "p45", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "4.4.4.6:45", IsLocal: true}, &BaseEndpointInfo{Endpoint: "4.4.4.6:45", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expected: map[types.NamespacedName]sets.String{ expected: map[types.NamespacedName]sets.String{
{Namespace: "ns2", Name: "ep2"}: sets.NewString("2.2.2.2", "2.2.2.22", "2.2.2.3"), {Namespace: "ns2", Name: "ep2"}: sets.NewString("2.2.2.2", "2.2.2.22", "2.2.2.3"),
{Namespace: "ns4", Name: "ep4"}: sets.NewString("4.4.4.4", "4.4.4.6"), {Namespace: "ns4", Name: "ep4"}: sets.NewString("4.4.4.4", "4.4.4.6"),
}, },
}, {
// Case[5]: named local and non-local ports for different IPs, some not ready.
endpointsMap: EndpointsMap{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
},
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "2.2.2.22:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
},
makeServicePortName("ns2", "ep2", "p23", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "2.2.2.3:23", IsLocal: true, Ready: false, Serving: true, Terminating: true},
},
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "4.4.4.5:44", IsLocal: false, Ready: true, Serving: true, Terminating: false},
},
makeServicePortName("ns4", "ep4", "p45", v1.ProtocolTCP): []Endpoint{
&BaseEndpointInfo{Endpoint: "4.4.4.6:45", IsLocal: true, Ready: true, Serving: true, Terminating: false},
},
},
expected: map[types.NamespacedName]sets.String{
{Namespace: "ns2", Name: "ep2"}: sets.NewString("2.2.2.2", "2.2.2.22"),
{Namespace: "ns4", Name: "ep4"}: sets.NewString("4.4.4.4", "4.4.4.6"),
},
}} }}
for tci, tc := range testCases { for tci, tc := range testCases {
// outputs // outputs
localIPs := tc.endpointsMap.getLocalEndpointIPs() localIPs := tc.endpointsMap.getLocalReadyEndpointIPs()
if !reflect.DeepEqual(localIPs, tc.expected) { if !reflect.DeepEqual(localIPs, tc.expected) {
t.Errorf("[%d] expected %#v, got %#v", tci, tc.expected, localIPs) t.Errorf("[%d] expected %#v, got %#v", tci, tc.expected, localIPs)
@ -169,7 +194,7 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -193,7 +218,7 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "port", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "port", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -216,7 +241,7 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -253,12 +278,12 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:11", IsLocal: false}, {Endpoint: "2.2.2.2:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:22", IsLocal: false}, {Endpoint: "1.1.1.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:22", IsLocal: false}, {Endpoint: "2.2.2.2:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -282,7 +307,7 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -306,7 +331,7 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -330,7 +355,7 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:22", IsLocal: false}, {Endpoint: "1.1.1.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -360,10 +385,10 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): {
{Endpoint: "1.1.1.1:22", IsLocal: false}, {Endpoint: "1.1.1.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -393,10 +418,10 @@ func TestEndpointsToEndpointsMap(t *testing.T) {
}), }),
expected: map[ServicePortName][]*BaseEndpointInfo{ expected: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p1", v1.ProtocolTCP): {
{Endpoint: "[2001:db8:85a3:0:0:8a2e:370:7334]:11", IsLocal: false}, {Endpoint: "[2001:db8:85a3:0:0:8a2e:370:7334]:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): { makeServicePortName("ns1", "ep1", "p2", v1.ProtocolTCP): {
{Endpoint: "[2001:db8:85a3:0:0:8a2e:370:7334]:22", IsLocal: false}, {Endpoint: "[2001:db8:85a3:0:0:8a2e:370:7334]:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -795,12 +820,12 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -816,12 +841,12 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -839,18 +864,18 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -866,24 +891,24 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: true}, {Endpoint: "1.1.1.1:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: true}, {Endpoint: "1.1.1.1:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -903,54 +928,54 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:13", IsLocal: true}, {Endpoint: "1.1.1.4:13", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:14", IsLocal: false}, {Endpoint: "1.1.1.3:14", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:14", IsLocal: true}, {Endpoint: "1.1.1.4:14", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:21", IsLocal: false}, {Endpoint: "2.2.2.1:21", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:21", IsLocal: true}, {Endpoint: "2.2.2.2:21", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:22", IsLocal: false}, {Endpoint: "2.2.2.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:22", IsLocal: true}, {Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:13", IsLocal: true}, {Endpoint: "1.1.1.4:13", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:14", IsLocal: false}, {Endpoint: "1.1.1.3:14", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:14", IsLocal: true}, {Endpoint: "1.1.1.4:14", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:21", IsLocal: false}, {Endpoint: "2.2.2.1:21", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:21", IsLocal: true}, {Endpoint: "2.2.2.2:21", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:22", IsLocal: false}, {Endpoint: "2.2.2.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:22", IsLocal: true}, {Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -970,7 +995,7 @@ func TestUpdateEndpointsMap(t *testing.T) {
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{}, oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{},
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -990,7 +1015,7 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{}, expectedResult: map[ServicePortName][]*BaseEndpointInfo{},
@ -1010,17 +1035,17 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -1040,17 +1065,17 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{{ expectedStaleEndpoints: []ServiceEndpoint{{
@ -1075,15 +1100,15 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -1103,15 +1128,15 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{{ expectedStaleEndpoints: []ServiceEndpoint{{
@ -1130,12 +1155,12 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11-2", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11-2", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{{ expectedStaleEndpoints: []ServiceEndpoint{{
@ -1156,12 +1181,12 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:22", IsLocal: false}, {Endpoint: "1.1.1.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{{ expectedStaleEndpoints: []ServiceEndpoint{{
@ -1186,39 +1211,39 @@ func TestUpdateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{ oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{Endpoint: "2.2.2.2:22", IsLocal: true}, {Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.22:22", IsLocal: true}, {Endpoint: "2.2.2.22:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p23", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p23", v1.ProtocolUDP): {
{Endpoint: "2.2.2.3:23", IsLocal: true}, {Endpoint: "2.2.2.3:23", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): {
{Endpoint: "4.4.4.4:44", IsLocal: true}, {Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
{Endpoint: "4.4.4.5:44", IsLocal: true}, {Endpoint: "4.4.4.5:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p45", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p45", v1.ProtocolUDP): {
{Endpoint: "4.4.4.6:45", IsLocal: true}, {Endpoint: "4.4.4.6:45", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.11:11", IsLocal: false}, {Endpoint: "1.1.1.11:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p122", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p122", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:122", IsLocal: false}, {Endpoint: "1.1.1.2:122", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns3", "ep3", "p33", v1.ProtocolUDP): { makeServicePortName("ns3", "ep3", "p33", v1.ProtocolUDP): {
{Endpoint: "3.3.3.3:33", IsLocal: false}, {Endpoint: "3.3.3.3:33", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): {
{Endpoint: "4.4.4.4:44", IsLocal: true}, {Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{{ expectedStaleEndpoints: []ServiceEndpoint{{
@ -1256,7 +1281,7 @@ func TestUpdateEndpointsMap(t *testing.T) {
oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{}, oldEndpoints: map[ServicePortName][]*BaseEndpointInfo{},
expectedResult: map[ServicePortName][]*BaseEndpointInfo{ expectedResult: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []ServiceEndpoint{}, expectedStaleEndpoints: []ServiceEndpoint{},
@ -1459,7 +1484,7 @@ func TestLastChangeTriggerTime(t *testing.T) {
} }
func TestEndpointSliceUpdate(t *testing.T) { func TestEndpointSliceUpdate(t *testing.T) {
fqdnSlice := generateEndpointSlice("svc1", "ns1", 2, 5, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}) fqdnSlice := generateEndpointSlice("svc1", "ns1", 2, 5, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)})
fqdnSlice.AddressType = discovery.AddressTypeFQDN fqdnSlice.AddressType = discovery.AddressTypeFQDN
testCases := map[string]struct { testCases := map[string]struct {
@ -1476,30 +1501,30 @@ func TestEndpointSliceUpdate(t *testing.T) {
startingSlices: []*discovery.EndpointSlice{}, startingSlices: []*discovery.EndpointSlice{},
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false, paramRemoveSlice: false,
expectedReturnVal: true, expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{ expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:443"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
// test no modification to state - current change should be nil as nothing changes // test no modification to state - current change should be nil as nothing changes
"add the same slice that already exists": { "add the same slice that already exists": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false, paramRemoveSlice: false,
expectedReturnVal: false, expectedReturnVal: false,
expectedCurrentChange: nil, expectedCurrentChange: nil,
@ -1507,7 +1532,7 @@ func TestEndpointSliceUpdate(t *testing.T) {
// ensure that only valide address types are processed // ensure that only valide address types are processed
"add an FQDN slice (invalid address type)": { "add an FQDN slice (invalid address type)": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
@ -1519,96 +1544,96 @@ func TestEndpointSliceUpdate(t *testing.T) {
// test additions to existing state // test additions to existing state
"add a slice that overlaps with existing state": { "add a slice that overlaps with existing state": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
generateEndpointSlice("svc1", "ns1", 2, 2, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 2, 2, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 5, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 5, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false, paramRemoveSlice: false,
expectedReturnVal: true, expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{ expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.4:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.5:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.5:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:443"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
// test additions to existing state with partially overlapping slices and ports // test additions to existing state with partially overlapping slices and ports
"add a slice that overlaps with existing state and partial ports": { "add a slice that overlaps with existing state and partial ports": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
generateEndpointSlice("svc1", "ns1", 2, 2, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 2, 2, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSliceWithOffset("svc1", "ns1", 3, 1, 5, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80)}), paramEndpointSlice: generateEndpointSliceWithOffset("svc1", "ns1", 3, 1, 5, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80)}),
paramRemoveSlice: false, paramRemoveSlice: false,
expectedReturnVal: true, expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{ expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:443"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:443"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
// test deletions from existing state with partially overlapping slices and ports // test deletions from existing state with partially overlapping slices and ports
"remove a slice that overlaps with existing state": { "remove a slice that overlaps with existing state": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
generateEndpointSlice("svc1", "ns1", 2, 2, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 2, 2, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 5, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 5, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: true, paramRemoveSlice: true,
expectedReturnVal: true, expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{ expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.2.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.2.1:443"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
// ensure a removal that has no effect turns into a no-op // ensure a removal that has no effect turns into a no-op
"remove a slice that doesn't even exist in current state": { "remove a slice that doesn't even exist in current state": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 5, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 5, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
generateEndpointSlice("svc1", "ns1", 2, 2, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 2, 2, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 3, 5, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 3, 5, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: true, paramRemoveSlice: true,
expectedReturnVal: false, expectedReturnVal: false,
expectedCurrentChange: nil, expectedCurrentChange: nil,
@ -1616,57 +1641,100 @@ func TestEndpointSliceUpdate(t *testing.T) {
// start with all endpoints ready, transition to no endpoints ready // start with all endpoints ready, transition to no endpoints ready
"transition all endpoints to unready state": { "transition all endpoints to unready state": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 1, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 1, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false,
expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{},
},
// start with no endpoints ready, transition to all endpoints ready
"transition all endpoints to ready state": {
startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 2, 1, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
},
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 2, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false, paramRemoveSlice: false,
expectedReturnVal: true, expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{ expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true, Ready: false, Serving: false, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: true, Ready: false, Serving: false, Terminating: false},
},
},
},
// start with no endpoints ready, transition to all endpoints ready
"transition all endpoints to ready state": {
startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 2, 1, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
},
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 2, 999, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false,
expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
},
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
// start with some endpoints ready, transition to more endpoints ready // start with some endpoints ready, transition to more endpoints ready
"transition some endpoints to ready state": { "transition some endpoints to ready state": {
startingSlices: []*discovery.EndpointSlice{ startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 2, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 2, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
generateEndpointSlice("svc1", "ns1", 2, 2, 2, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 2, 2, 2, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 3, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 3, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false, paramRemoveSlice: false,
expectedReturnVal: true, expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{ expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true, Ready: false, Serving: false, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true, Ready: false, Serving: false, Terminating: false},
},
},
},
// start with some endpoints ready, transition to some terminating
"transition some endpoints to terminating state": {
startingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 2, 2, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
generateEndpointSlice("svc1", "ns1", 2, 2, 2, 2, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
},
endpointChangeTracker: NewEndpointChangeTracker("host1", nil, v1.IPv4Protocol, nil, true, nil),
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
paramEndpointSlice: generateEndpointSlice("svc1", "ns1", 1, 3, 3, 2, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
paramRemoveSlice: false,
expectedReturnVal: true,
expectedCurrentChange: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: false, Serving: true, Terminating: true},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: true, Ready: false, Serving: false, Terminating: true},
},
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: false, Serving: true, Terminating: true},
&BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: true, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:443", IsLocal: true, Ready: false, Serving: false, Terminating: true},
}, },
}, },
}, },
@ -1727,21 +1795,21 @@ func TestCheckoutChanges(t *testing.T) {
endpointChangeTracker: NewEndpointChangeTracker("", nil, v1.IPv4Protocol, nil, false, nil), endpointChangeTracker: NewEndpointChangeTracker("", nil, v1.IPv4Protocol, nil, false, nil),
expectedChanges: []*endpointsChange{{ expectedChanges: []*endpointsChange{{
previous: EndpointsMap{ previous: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", ""), newTestEp("10.0.1.2:80", "")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "", true, true, false), newTestEp("10.0.1.2:80", "", true, true, false)},
svcPortName1: []Endpoint{newTestEp("10.0.1.1:443", ""), newTestEp("10.0.1.2:443", "")}, svcPortName1: []Endpoint{newTestEp("10.0.1.1:443", "", true, true, false), newTestEp("10.0.1.2:443", "", true, true, false)},
}, },
current: EndpointsMap{ current: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", ""), newTestEp("10.0.1.2:80", "")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "", true, true, false), newTestEp("10.0.1.2:80", "", true, true, false)},
}, },
}}, }},
items: map[types.NamespacedName]*endpointsChange{ items: map[types.NamespacedName]*endpointsChange{
{Namespace: "ns1", Name: "svc1"}: { {Namespace: "ns1", Name: "svc1"}: {
previous: EndpointsMap{ previous: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", ""), newTestEp("10.0.1.2:80", "")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "", true, true, false), newTestEp("10.0.1.2:80", "", true, true, false)},
svcPortName1: []Endpoint{newTestEp("10.0.1.1:443", ""), newTestEp("10.0.1.2:443", "")}, svcPortName1: []Endpoint{newTestEp("10.0.1.1:443", "", true, true, false), newTestEp("10.0.1.2:443", "", true, true, false)},
}, },
current: EndpointsMap{ current: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", ""), newTestEp("10.0.1.2:80", "")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "", true, true, false), newTestEp("10.0.1.2:80", "", true, true, false)},
}, },
}, },
}, },
@ -1752,32 +1820,32 @@ func TestCheckoutChanges(t *testing.T) {
expectedChanges: []*endpointsChange{{ expectedChanges: []*endpointsChange{{
previous: EndpointsMap{}, previous: EndpointsMap{},
current: EndpointsMap{ current: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "host1"), newTestEp("10.0.1.2:80", "host1")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "host1", true, true, false), newTestEp("10.0.1.2:80", "host1", false, true, true), newTestEp("10.0.1.3:80", "host1", false, false, false)},
}, },
}}, }},
useEndpointSlices: true, useEndpointSlices: true,
appliedSlices: []*discovery.EndpointSlice{}, appliedSlices: []*discovery.EndpointSlice{},
pendingSlices: []*discovery.EndpointSlice{ pendingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 3, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 3, 3, 2, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
}, },
"removing port in update": { "removing port in update": {
endpointChangeTracker: NewEndpointChangeTracker("", nil, v1.IPv4Protocol, nil, true, nil), endpointChangeTracker: NewEndpointChangeTracker("", nil, v1.IPv4Protocol, nil, true, nil),
expectedChanges: []*endpointsChange{{ expectedChanges: []*endpointsChange{{
previous: EndpointsMap{ previous: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "host1"), newTestEp("10.0.1.2:80", "host1")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "host1", true, true, false), newTestEp("10.0.1.2:80", "host1", true, true, false), newTestEp("10.0.1.3:80", "host1", false, false, false)},
svcPortName1: []Endpoint{newTestEp("10.0.1.1:443", "host1"), newTestEp("10.0.1.2:443", "host1")}, svcPortName1: []Endpoint{newTestEp("10.0.1.1:443", "host1", true, true, false), newTestEp("10.0.1.2:443", "host1", true, true, false), newTestEp("10.0.1.3:443", "host1", false, false, false)},
}, },
current: EndpointsMap{ current: EndpointsMap{
svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "host1"), newTestEp("10.0.1.2:80", "host1")}, svcPortName0: []Endpoint{newTestEp("10.0.1.1:80", "host1", true, true, false), newTestEp("10.0.1.2:80", "host1", true, true, false), newTestEp("10.0.1.3:80", "host1", false, false, false)},
}, },
}}, }},
useEndpointSlices: true, useEndpointSlices: true,
appliedSlices: []*discovery.EndpointSlice{ appliedSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 3, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 3, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
pendingSlices: []*discovery.EndpointSlice{ pendingSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 3, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 3, 3, 999, []string{"host1"}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
}, },
} }
@ -1825,7 +1893,7 @@ func compareEndpointsMapsStr(t *testing.T, newMap EndpointsMap, expected map[Ser
t.Fatalf("expected %d results, got %d: %v", len(expected), len(newMap), newMap) t.Fatalf("expected %d results, got %d: %v", len(expected), len(newMap), newMap)
} }
endpointEqual := func(a, b *BaseEndpointInfo) bool { endpointEqual := func(a, b *BaseEndpointInfo) bool {
return a.Endpoint == b.Endpoint && a.IsLocal == b.IsLocal return a.Endpoint == b.Endpoint && a.IsLocal == b.IsLocal && a.Ready == b.Ready && a.Serving == b.Serving && a.Terminating == b.Terminating
} }
for x := range expected { for x := range expected {
if len(newMap[x]) != len(expected[x]) { if len(newMap[x]) != len(expected[x]) {
@ -1839,15 +1907,18 @@ func compareEndpointsMapsStr(t *testing.T, newMap EndpointsMap, expected map[Ser
continue continue
} }
if !endpointEqual(newEp, expected[x][i]) { if !endpointEqual(newEp, expected[x][i]) {
t.Fatalf("expected new[%v][%d] to be %v, got %v (IsLocal expected %v, got %v)", x, i, expected[x][i], newEp, expected[x][i].IsLocal, newEp.IsLocal) t.Fatalf("expected new[%v][%d] to be %v, got %v"+
"(IsLocal expected %v, got %v) (Ready expected %v, got %v) (Serving expected %v, got %v) (Terminating expected %v got %v)",
x, i, expected[x][i], newEp, expected[x][i].IsLocal, newEp.IsLocal, expected[x][i].Ready, newEp.Ready,
expected[x][i].Serving, newEp.Serving, expected[x][i].Terminating, newEp.Terminating)
} }
} }
} }
} }
} }
func newTestEp(ep, host string) *BaseEndpointInfo { func newTestEp(ep, host string, ready, serving, terminating bool) *BaseEndpointInfo {
endpointInfo := &BaseEndpointInfo{Endpoint: ep} endpointInfo := &BaseEndpointInfo{Endpoint: ep, Ready: ready, Serving: serving, Terminating: terminating}
if host != "" { if host != "" {
endpointInfo.Topology = map[string]string{ endpointInfo.Topology = map[string]string{
"kubernetes.io/hostname": host, "kubernetes.io/hostname": host,

View File

@ -80,6 +80,10 @@ type endpointInfo struct {
Addresses []string Addresses []string
NodeName *string NodeName *string
Topology map[string]string Topology map[string]string
Ready bool
Serving bool
Terminating bool
} }
// spToEndpointMap stores groups Endpoint objects by ServicePortName and // spToEndpointMap stores groups Endpoint objects by ServicePortName and
@ -122,16 +126,21 @@ func newEndpointSliceInfo(endpointSlice *discovery.EndpointSlice, remove bool) *
if !remove { if !remove {
for _, endpoint := range endpointSlice.Endpoints { for _, endpoint := range endpointSlice.Endpoints {
if endpoint.Conditions.Ready == nil || *endpoint.Conditions.Ready { epInfo := &endpointInfo{
eInfo := endpointInfo{
Addresses: endpoint.Addresses, Addresses: endpoint.Addresses,
Topology: endpoint.Topology, Topology: endpoint.Topology,
// conditions
Ready: endpoint.Conditions.Ready == nil || *endpoint.Conditions.Ready,
Serving: endpoint.Conditions.Serving == nil || *endpoint.Conditions.Serving,
Terminating: endpoint.Conditions.Terminating != nil && *endpoint.Conditions.Terminating,
} }
if utilfeature.DefaultFeatureGate.Enabled(features.EndpointSliceNodeName) { if utilfeature.DefaultFeatureGate.Enabled(features.EndpointSliceNodeName) {
eInfo.NodeName = endpoint.NodeName epInfo.NodeName = endpoint.NodeName
}
esInfo.Endpoints = append(esInfo.Endpoints, &eInfo)
} }
esInfo.Endpoints = append(esInfo.Endpoints, epInfo)
} }
sort.Sort(byAddress(esInfo.Endpoints)) sort.Sort(byAddress(esInfo.Endpoints))
@ -269,7 +278,8 @@ func (cache *EndpointSliceCache) addEndpointsByIP(serviceNN types.NamespacedName
isLocal = cache.isLocal(endpoint.Topology[v1.LabelHostname]) isLocal = cache.isLocal(endpoint.Topology[v1.LabelHostname])
} }
endpointInfo := newBaseEndpointInfo(endpoint.Addresses[0], portNum, isLocal, endpoint.Topology) endpointInfo := newBaseEndpointInfo(endpoint.Addresses[0], portNum, isLocal, endpoint.Topology,
endpoint.Ready, endpoint.Serving, endpoint.Terminating)
// This logic ensures we're deduping potential overlapping endpoints // This logic ensures we're deduping potential overlapping endpoints
// isLocal should not vary between matching IPs, but if it does, we // isLocal should not vary between matching IPs, but if it does, we

View File

@ -40,35 +40,35 @@ func TestEndpointsMapFromESC(t *testing.T) {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
hostname: "host1", hostname: "host1",
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80), utilpointer.Int32Ptr(443)}),
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{ expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-1", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: false}, &BaseEndpointInfo{Endpoint: "10.0.1.1:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true}, &BaseEndpointInfo{Endpoint: "10.0.1.2:443", IsLocal: true, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: false}, &BaseEndpointInfo{Endpoint: "10.0.1.3:443", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
"2 slices, same port": { "2 slices, same port": {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc1", "ns1", 2, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 2, 3, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{ expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.2.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.2:80"}, &BaseEndpointInfo{Endpoint: "10.0.2.2:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.2.3:80"}, &BaseEndpointInfo{Endpoint: "10.0.2.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -77,15 +77,15 @@ func TestEndpointsMapFromESC(t *testing.T) {
"2 overlapping slices, same port": { "2 overlapping slices, same port": {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc1", "ns1", 1, 4, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 4, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{ expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -96,43 +96,79 @@ func TestEndpointsMapFromESC(t *testing.T) {
"2 slices, overlapping endpoints, some endpoints unready in 1 or both": { "2 slices, overlapping endpoints, some endpoints unready in 1 or both": {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 10, 3, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 10, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc1", "ns1", 1, 10, 6, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 10, 6, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{ expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.10:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.10:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.5:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.7:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.6:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.8:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.7:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.9:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.8:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.9:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
},
},
},
// 2 slices with all endpoints overlapping, some unready and terminating.
"2 slices, overlapping endpoints, some endpoints unready and some endpoints terminating": {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 10, 3, 5, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc1", "ns1", 1, 10, 6, 5, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
},
expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.10:80", IsLocal: false, Ready: false, Serving: true, Terminating: true},
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: false, Ready: false, Serving: true, Terminating: true},
&BaseEndpointInfo{Endpoint: "10.0.1.6:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.7:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.8:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.9:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
"2 slices, overlapping endpoints, all unready": { "2 slices, overlapping endpoints, all unready": {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 10, 1, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 10, 1, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc1", "ns1", 1, 10, 1, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 10, 1, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
},
expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.10:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.4:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.5:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.6:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.7:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.8:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.9:80", IsLocal: false, Ready: false, Serving: false, Terminating: false},
},
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{},
}, },
"3 slices with different services and namespaces": { "3 slices with different services and namespaces": {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc2", "ns1", 2, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc2", "ns1", 2, 3, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
generateEndpointSlice("svc1", "ns2", 3, 3, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns2", 3, 3, 999, 999, []string{}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{ expectedMap: map[ServicePortName][]*BaseEndpointInfo{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
&BaseEndpointInfo{Endpoint: "10.0.1.1:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.2:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
&BaseEndpointInfo{Endpoint: "10.0.1.3:80"}, &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
}, },
@ -143,7 +179,7 @@ func TestEndpointsMapFromESC(t *testing.T) {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
hostname: "host1", hostname: "host1",
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{nil}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{nil}),
}, },
expectedMap: map[ServicePortName][]*BaseEndpointInfo{}, expectedMap: map[ServicePortName][]*BaseEndpointInfo{},
}, },
@ -175,13 +211,34 @@ func TestEndpointInfoByServicePort(t *testing.T) {
namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"}, namespacedName: types.NamespacedName{Name: "svc1", Namespace: "ns1"},
hostname: "host1", hostname: "host1",
endpointSlices: []*discovery.EndpointSlice{ endpointSlices: []*discovery.EndpointSlice{
generateEndpointSlice("svc1", "ns1", 1, 3, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80)}), generateEndpointSlice("svc1", "ns1", 1, 3, 999, 999, []string{"host1", "host2"}, []*int32{utilpointer.Int32Ptr(80)}),
}, },
expectedMap: spToEndpointMap{ expectedMap: spToEndpointMap{
makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): { makeServicePortName("ns1", "svc1", "port-0", v1.ProtocolTCP): {
"10.0.1.1": &BaseEndpointInfo{Endpoint: "10.0.1.1:80", IsLocal: false, Topology: map[string]string{"kubernetes.io/hostname": "host2"}}, "10.0.1.1": &BaseEndpointInfo{
"10.0.1.2": &BaseEndpointInfo{Endpoint: "10.0.1.2:80", IsLocal: true, Topology: map[string]string{"kubernetes.io/hostname": "host1"}}, Endpoint: "10.0.1.1:80",
"10.0.1.3": &BaseEndpointInfo{Endpoint: "10.0.1.3:80", IsLocal: false, Topology: map[string]string{"kubernetes.io/hostname": "host2"}}, IsLocal: false,
Topology: map[string]string{"kubernetes.io/hostname": "host2"},
Ready: true,
Serving: true,
Terminating: false,
},
"10.0.1.2": &BaseEndpointInfo{
Endpoint: "10.0.1.2:80",
IsLocal: true,
Topology: map[string]string{"kubernetes.io/hostname": "host1"},
Ready: true,
Serving: true,
Terminating: false,
},
"10.0.1.3": &BaseEndpointInfo{
Endpoint: "10.0.1.3:80",
IsLocal: false,
Topology: map[string]string{"kubernetes.io/hostname": "host2"},
Ready: true,
Serving: true,
Terminating: false,
},
}, },
}, },
}, },
@ -342,7 +399,7 @@ func TestEsInfoChanged(t *testing.T) {
} }
} }
func generateEndpointSliceWithOffset(serviceName, namespace string, sliceNum, offset, numEndpoints, unreadyMod int, hosts []string, portNums []*int32) *discovery.EndpointSlice { func generateEndpointSliceWithOffset(serviceName, namespace string, sliceNum, offset, numEndpoints, unreadyMod int, terminatingMod int, hosts []string, portNums []*int32) *discovery.EndpointSlice {
tcpProtocol := v1.ProtocolTCP tcpProtocol := v1.ProtocolTCP
endpointSlice := &discovery.EndpointSlice{ endpointSlice := &discovery.EndpointSlice{
@ -365,9 +422,20 @@ func generateEndpointSliceWithOffset(serviceName, namespace string, sliceNum, of
} }
for i := 1; i <= numEndpoints; i++ { for i := 1; i <= numEndpoints; i++ {
readyCondition := i%unreadyMod != 0
terminatingCondition := i%terminatingMod == 0
ready := utilpointer.BoolPtr(readyCondition && !terminatingCondition)
serving := utilpointer.BoolPtr(readyCondition)
terminating := utilpointer.BoolPtr(terminatingCondition)
endpoint := discovery.Endpoint{ endpoint := discovery.Endpoint{
Addresses: []string{fmt.Sprintf("10.0.%d.%d", offset, i)}, Addresses: []string{fmt.Sprintf("10.0.%d.%d", offset, i)},
Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(i%unreadyMod != 0)}, Conditions: discovery.EndpointConditions{
Ready: ready,
Serving: serving,
Terminating: terminating,
},
} }
if len(hosts) > 0 { if len(hosts) > 0 {
@ -382,8 +450,8 @@ func generateEndpointSliceWithOffset(serviceName, namespace string, sliceNum, of
return endpointSlice return endpointSlice
} }
func generateEndpointSlice(serviceName, namespace string, sliceNum, numEndpoints, unreadyMod int, hosts []string, portNums []*int32) *discovery.EndpointSlice { func generateEndpointSlice(serviceName, namespace string, sliceNum, numEndpoints, unreadyMod int, terminatingMod int, hosts []string, portNums []*int32) *discovery.EndpointSlice {
return generateEndpointSliceWithOffset(serviceName, namespace, sliceNum, sliceNum, numEndpoints, unreadyMod, hosts, portNums) return generateEndpointSliceWithOffset(serviceName, namespace, sliceNum, sliceNum, numEndpoints, unreadyMod, terminatingMod, hosts, portNums)
} }
// cacheMutationCheck helps ensure that cached objects have not been changed // cacheMutationCheck helps ensure that cached objects have not been changed

View File

@ -1020,8 +1020,6 @@ func (proxier *Proxier) syncProxyRules() {
allEndpoints := proxier.endpointsMap[svcName] allEndpoints := proxier.endpointsMap[svcName]
hasEndpoints := len(allEndpoints) > 0
// Service Topology will not be enabled in the following cases: // Service Topology will not be enabled in the following cases:
// 1. externalTrafficPolicy=Local (mutually exclusive with service topology). // 1. externalTrafficPolicy=Local (mutually exclusive with service topology).
// 2. ServiceTopology is not enabled. // 2. ServiceTopology is not enabled.
@ -1029,9 +1027,18 @@ func (proxier *Proxier) syncProxyRules() {
// to get topology information). // to get topology information).
if !svcInfo.OnlyNodeLocalEndpoints() && utilfeature.DefaultFeatureGate.Enabled(features.ServiceTopology) && utilfeature.DefaultFeatureGate.Enabled(features.EndpointSliceProxying) { if !svcInfo.OnlyNodeLocalEndpoints() && utilfeature.DefaultFeatureGate.Enabled(features.ServiceTopology) && utilfeature.DefaultFeatureGate.Enabled(features.EndpointSliceProxying) {
allEndpoints = proxy.FilterTopologyEndpoint(proxier.nodeLabels, svcInfo.TopologyKeys(), allEndpoints) allEndpoints = proxy.FilterTopologyEndpoint(proxier.nodeLabels, svcInfo.TopologyKeys(), allEndpoints)
hasEndpoints = len(allEndpoints) > 0
} }
readyEndpoints := make([]proxy.Endpoint, 0, len(allEndpoints))
for _, endpoint := range allEndpoints {
if !endpoint.IsReady() {
continue
}
readyEndpoints = append(readyEndpoints, endpoint)
}
hasEndpoints := len(readyEndpoints) > 0
svcChain := svcInfo.servicePortChainName svcChain := svcInfo.servicePortChainName
if hasEndpoints { if hasEndpoints {
// Create the per-service chain, retaining counters if possible. // Create the per-service chain, retaining counters if possible.
@ -1340,7 +1347,7 @@ func (proxier *Proxier) syncProxyRules() {
endpoints = endpoints[:0] endpoints = endpoints[:0]
endpointChains = endpointChains[:0] endpointChains = endpointChains[:0]
var endpointChain utiliptables.Chain var endpointChain utiliptables.Chain
for _, ep := range allEndpoints { for _, ep := range readyEndpoints {
epInfo, ok := ep.(*endpointsInfo) epInfo, ok := ep.(*endpointsInfo)
if !ok { if !ok {
klog.ErrorS(err, "Failed to cast endpointsInfo", "endpointsInfo", ep.String()) klog.ErrorS(err, "Failed to cast endpointsInfo", "endpointsInfo", ep.String())

View File

@ -2044,12 +2044,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2065,12 +2065,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2088,18 +2088,18 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2115,24 +2115,24 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2152,54 +2152,54 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:13", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:13", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:14", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:14", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:14", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:14", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:21", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:21", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:21", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:21", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:22", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:13", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:13", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:14", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.3:14", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:14", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.4:14", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:21", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:21", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:21", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:21", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:22", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2219,7 +2219,7 @@ func Test_updateEndpointsMap(t *testing.T) {
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{}, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{},
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2239,7 +2239,7 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{}, expectedResult: map[proxy.ServicePortName][]*endpointsInfo{},
@ -2259,17 +2259,17 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2289,17 +2289,17 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -2324,15 +2324,15 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2352,15 +2352,15 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -2379,12 +2379,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11-2", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11-2", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -2405,12 +2405,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:22", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -2435,39 +2435,39 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{ oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.22:22", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.22:22", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns2", "ep2", "p23", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p23", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.3:23", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "2.2.2.3:23", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.5:44", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.5:44", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns4", "ep4", "p45", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p45", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.6:45", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.6:45", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.11:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.11:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns1", "ep1", "p122", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p122", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:122", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.2:122", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns3", "ep3", "p33", v1.ProtocolUDP): { makeServicePortName("ns3", "ep3", "p33", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "3.3.3.3:33", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "3.3.3.3:33", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -2505,7 +2505,7 @@ func Test_updateEndpointsMap(t *testing.T) {
oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{}, oldEndpoints: map[proxy.ServicePortName][]*endpointsInfo{},
expectedResult: map[proxy.ServicePortName][]*endpointsInfo{ expectedResult: map[proxy.ServicePortName][]*endpointsInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false}}, {BaseEndpointInfo: &proxy.BaseEndpointInfo{Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false}},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2670,6 +2670,10 @@ COMMIT
Addresses: []string{"10.0.1.3"}, Addresses: []string{"10.0.1.3"},
Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(true)}, Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(true)},
Topology: map[string]string{"kubernetes.io/hostname": "node3"}, Topology: map[string]string{"kubernetes.io/hostname": "node3"},
}, { // not ready endpoints should be ignored
Addresses: []string{"10.0.1.4"},
Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(false)},
Topology: map[string]string{"kubernetes.io/hostname": "node4"},
}}, }},
} }

View File

@ -2036,9 +2036,14 @@ func (proxier *Proxier) syncEndpoint(svcPortName proxy.ServicePortName, onlyNode
} }
for _, epInfo := range endpoints { for _, epInfo := range endpoints {
if !epInfo.IsReady() {
continue
}
if onlyNodeLocalEndpoints && !epInfo.GetIsLocal() { if onlyNodeLocalEndpoints && !epInfo.GetIsLocal() {
continue continue
} }
newEndpoints.Insert(epInfo.String()) newEndpoints.Insert(epInfo.String())
} }

View File

@ -2881,12 +2881,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2902,12 +2902,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2925,18 +2925,18 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2952,24 +2952,24 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: true}, {Endpoint: "1.1.1.1:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: true}, {Endpoint: "1.1.1.1:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -2989,54 +2989,54 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:13", IsLocal: true}, {Endpoint: "1.1.1.4:13", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:14", IsLocal: false}, {Endpoint: "1.1.1.3:14", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:14", IsLocal: true}, {Endpoint: "1.1.1.4:14", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:21", IsLocal: false}, {Endpoint: "2.2.2.1:21", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:21", IsLocal: true}, {Endpoint: "2.2.2.2:21", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:22", IsLocal: false}, {Endpoint: "2.2.2.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:22", IsLocal: true}, {Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p13", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:13", IsLocal: false}, {Endpoint: "1.1.1.3:13", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:13", IsLocal: true}, {Endpoint: "1.1.1.4:13", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p14", v1.ProtocolUDP): {
{Endpoint: "1.1.1.3:14", IsLocal: false}, {Endpoint: "1.1.1.3:14", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.4:14", IsLocal: true}, {Endpoint: "1.1.1.4:14", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p21", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:21", IsLocal: false}, {Endpoint: "2.2.2.1:21", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:21", IsLocal: true}, {Endpoint: "2.2.2.2:21", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{Endpoint: "2.2.2.1:22", IsLocal: false}, {Endpoint: "2.2.2.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.2:22", IsLocal: true}, {Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -3056,7 +3056,7 @@ func Test_updateEndpointsMap(t *testing.T) {
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{}, oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{},
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -3076,7 +3076,7 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: true}, {Endpoint: "1.1.1.1:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{}, expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{},
@ -3096,17 +3096,17 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -3126,17 +3126,17 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:11", IsLocal: true}, {Endpoint: "1.1.1.2:11", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:12", IsLocal: false}, {Endpoint: "1.1.1.1:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -3161,15 +3161,15 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: true}, {Endpoint: "1.1.1.2:12", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -3189,15 +3189,15 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -3216,12 +3216,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11-2", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11-2", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -3242,12 +3242,12 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:22", IsLocal: false}, {Endpoint: "1.1.1.1:22", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -3272,39 +3272,39 @@ func Test_updateEndpointsMap(t *testing.T) {
}, },
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p22", v1.ProtocolUDP): {
{Endpoint: "2.2.2.2:22", IsLocal: true}, {Endpoint: "2.2.2.2:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
{Endpoint: "2.2.2.22:22", IsLocal: true}, {Endpoint: "2.2.2.22:22", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns2", "ep2", "p23", v1.ProtocolUDP): { makeServicePortName("ns2", "ep2", "p23", v1.ProtocolUDP): {
{Endpoint: "2.2.2.3:23", IsLocal: true}, {Endpoint: "2.2.2.3:23", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): {
{Endpoint: "4.4.4.4:44", IsLocal: true}, {Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
{Endpoint: "4.4.4.5:44", IsLocal: true}, {Endpoint: "4.4.4.5:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p45", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p45", v1.ProtocolUDP): {
{Endpoint: "4.4.4.6:45", IsLocal: true}, {Endpoint: "4.4.4.6:45", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p11", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
{Endpoint: "1.1.1.11:11", IsLocal: false}, {Endpoint: "1.1.1.11:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p12", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:12", IsLocal: false}, {Endpoint: "1.1.1.2:12", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns1", "ep1", "p122", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "p122", v1.ProtocolUDP): {
{Endpoint: "1.1.1.2:122", IsLocal: false}, {Endpoint: "1.1.1.2:122", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns3", "ep3", "p33", v1.ProtocolUDP): { makeServicePortName("ns3", "ep3", "p33", v1.ProtocolUDP): {
{Endpoint: "3.3.3.3:33", IsLocal: false}, {Endpoint: "3.3.3.3:33", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): { makeServicePortName("ns4", "ep4", "p44", v1.ProtocolUDP): {
{Endpoint: "4.4.4.4:44", IsLocal: true}, {Endpoint: "4.4.4.4:44", IsLocal: true, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{{ expectedStaleEndpoints: []proxy.ServiceEndpoint{{
@ -3342,7 +3342,7 @@ func Test_updateEndpointsMap(t *testing.T) {
oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{}, oldEndpoints: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{},
expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{ expectedResult: map[proxy.ServicePortName][]*proxy.BaseEndpointInfo{
makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): { makeServicePortName("ns1", "ep1", "", v1.ProtocolUDP): {
{Endpoint: "1.1.1.1:11", IsLocal: false}, {Endpoint: "1.1.1.1:11", IsLocal: false, Ready: true, Serving: true, Terminating: false},
}, },
}, },
expectedStaleEndpoints: []proxy.ServiceEndpoint{}, expectedStaleEndpoints: []proxy.ServiceEndpoint{},
@ -4256,6 +4256,10 @@ func TestEndpointSliceE2E(t *testing.T) {
Addresses: []string{"10.0.1.3"}, Addresses: []string{"10.0.1.3"},
Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(true)}, Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(true)},
Topology: map[string]string{"kubernetes.io/hostname": "node3"}, Topology: map[string]string{"kubernetes.io/hostname": "node3"},
}, { // not ready endpoints should be ignored
Addresses: []string{"10.0.1.4"},
Conditions: discovery.EndpointConditions{Ready: utilpointer.BoolPtr(false)},
Topology: map[string]string{"kubernetes.io/hostname": "node3"},
}}, }},
} }

View File

@ -97,6 +97,20 @@ type Endpoint interface {
String() string String() string
// GetIsLocal returns true if the endpoint is running in same host as kube-proxy, otherwise returns false. // GetIsLocal returns true if the endpoint is running in same host as kube-proxy, otherwise returns false.
GetIsLocal() bool GetIsLocal() bool
// IsReady returns true if an endpoint is ready and not terminating.
// This is only set when watching EndpointSlices. If using Endpoints, this is always
// true since only ready endpoints are read from Endpoints.
IsReady() bool
// IsServing returns true if an endpoint is ready. It does not account
// for terminating state.
// This is only set when watching EndpointSlices. If using Endpoints, this is always
// true since only ready endpoints are read from Endpoints.
IsServing() bool
// IsTerminating retruns true if an endpoint is terminating. For pods,
// that is any pod with a deletion timestamp.
// This is only set when watching EndpointSlices. If using Endpoints, this is always
// false since terminating endpoints are always excluded from Endpoints.
IsTerminating() bool
// GetTopology returns the topology information of the endpoint. // GetTopology returns the topology information of the endpoint.
GetTopology() map[string]string GetTopology() map[string]string
// IP returns IP part of the endpoint. // IP returns IP part of the endpoint.

View File

@ -65,6 +65,11 @@ func (hns hnsV1) getEndpointByID(id string) (*endpointsInfo, error) {
macAddress: hnsendpoint.MacAddress, macAddress: hnsendpoint.MacAddress,
hnsID: hnsendpoint.Id, hnsID: hnsendpoint.Id,
hns: hns, hns: hns,
// only ready and not terminating endpoints were added to HNS
ready: true,
serving: true,
terminating: false,
}, nil }, nil
} }
func (hns hnsV1) getEndpointByIpAddress(ip string, networkName string) (*endpointsInfo, error) { func (hns hnsV1) getEndpointByIpAddress(ip string, networkName string) (*endpointsInfo, error) {
@ -90,6 +95,11 @@ func (hns hnsV1) getEndpointByIpAddress(ip string, networkName string) (*endpoin
macAddress: endpoint.MacAddress, macAddress: endpoint.MacAddress,
hnsID: endpoint.Id, hnsID: endpoint.Id,
hns: hns, hns: hns,
// only ready and not terminating endpoints were added to HNS
ready: true,
serving: true,
terminating: false,
}, nil }, nil
} }
} }
@ -137,6 +147,10 @@ func (hns hnsV1) createEndpoint(ep *endpointsInfo, networkName string) (*endpoin
hnsID: createdEndpoint.Id, hnsID: createdEndpoint.Id,
providerAddress: ep.providerAddress, //TODO get from createdEndpoint providerAddress: ep.providerAddress, //TODO get from createdEndpoint
hns: hns, hns: hns,
ready: ep.ready,
serving: ep.serving,
terminating: ep.terminating,
}, nil }, nil
} }
func (hns hnsV1) deleteEndpoint(hnsID string) error { func (hns hnsV1) deleteEndpoint(hnsID string) error {

View File

@ -162,6 +162,11 @@ type endpointsInfo struct {
refCount *uint16 refCount *uint16
providerAddress string providerAddress string
hns HostNetworkService hns HostNetworkService
// conditions
ready bool
serving bool
terminating bool
} }
// String is part of proxy.Endpoint interface. // String is part of proxy.Endpoint interface.
@ -174,6 +179,21 @@ func (info *endpointsInfo) GetIsLocal() bool {
return info.isLocal return info.isLocal
} }
// IsReady returns true if an endpoint is ready and not terminating.
func (info *endpointsInfo) IsReady() bool {
return info.ready
}
// IsServing returns true if an endpoint is ready, regardless of it's terminating state.
func (info *endpointsInfo) IsServing() bool {
return info.serving
}
// IsTerminating returns true if an endpoint is terminating.
func (info *endpointsInfo) IsTerminating() bool {
return info.terminating
}
// GetTopology returns the topology information of the endpoint. // GetTopology returns the topology information of the endpoint.
func (info *endpointsInfo) GetTopology() map[string]string { func (info *endpointsInfo) GetTopology() map[string]string {
return nil return nil
@ -300,6 +320,10 @@ func (proxier *Proxier) newEndpointInfo(baseInfo *proxy.BaseEndpointInfo) proxy.
refCount: new(uint16), refCount: new(uint16),
hnsID: "", hnsID: "",
hns: proxier.hns, hns: proxier.hns,
ready: baseInfo.Ready,
serving: baseInfo.Serving,
terminating: baseInfo.Terminating,
} }
return info return info
@ -311,6 +335,10 @@ func newSourceVIP(hns HostNetworkService, network string, ip string, mac string,
isLocal: true, isLocal: true,
macAddress: mac, macAddress: mac,
providerAddress: providerAddress, providerAddress: providerAddress,
ready: true,
serving: true,
terminating: false,
} }
ep, err := hns.createEndpoint(hnsEndpoint, network) ep, err := hns.createEndpoint(hnsEndpoint, network)
return ep, err return ep, err
@ -1010,13 +1038,16 @@ func (proxier *Proxier) syncProxyRules() {
containsNodeIP := false containsNodeIP := false
for _, epInfo := range proxier.endpointsMap[svcName] { for _, epInfo := range proxier.endpointsMap[svcName] {
ep, ok := epInfo.(*endpointsInfo) ep, ok := epInfo.(*endpointsInfo)
if !ok { if !ok {
klog.Errorf("Failed to cast endpointsInfo %q", svcName.String()) klog.Errorf("Failed to cast endpointsInfo %q", svcName.String())
continue continue
} }
if !ep.IsReady() {
continue
}
var newHnsEndpoint *endpointsInfo var newHnsEndpoint *endpointsInfo
hnsNetworkName := proxier.network.name hnsNetworkName := proxier.network.name
var err error var err error