Make EndpointSlice mirroring controller always canonicalize the IPs it writes out

(Also rearrange some code to avoid parsing the IP twice.)
This commit is contained in:
Dan Winship 2025-02-11 17:43:17 -05:00
parent 29be52b3f7
commit 6512de76ce
4 changed files with 19 additions and 21 deletions

View File

@ -87,8 +87,7 @@ func (d *desiredCalc) initPorts(subsetPorts []v1.EndpointPort) multiAddrTypePort
// addAddress adds an EndpointAddress to the desired state if it is valid. It // addAddress adds an EndpointAddress to the desired state if it is valid. It
// returns false if the address was invalid. // returns false if the address was invalid.
func (d *desiredCalc) addAddress(address v1.EndpointAddress, multiKey multiAddrTypePortMapKey, ready bool) bool { func (d *desiredCalc) addAddress(address v1.EndpointAddress, multiKey multiAddrTypePortMapKey, ready bool) bool {
endpoint := addressToEndpoint(address, ready) endpoint, addrType := addressToEndpoint(address, ready)
addrType := getAddressType(address.IP)
if addrType == nil { if addrType == nil {
return false return false
} }

View File

@ -1245,7 +1245,7 @@ func expectMatchingAddresses(t *testing.T, epSubset corev1.EndpointSubset, esEnd
expectedEndpoints := map[string]addressInfo{} expectedEndpoints := map[string]addressInfo{}
for _, address := range epSubset.Addresses { for _, address := range epSubset.Addresses {
at := getAddressType(address.IP) _, at := addressToEndpoint(address, true)
if at != nil && *at == addrType && len(expectedEndpoints) < maxEndpointsPerSubset { if at != nil && *at == addrType && len(expectedEndpoints) < maxEndpointsPerSubset {
expectedEndpoints[address.IP] = addressInfo{ expectedEndpoints[address.IP] = addressInfo{
ready: true, ready: true,
@ -1255,7 +1255,7 @@ func expectMatchingAddresses(t *testing.T, epSubset corev1.EndpointSubset, esEnd
} }
for _, address := range epSubset.NotReadyAddresses { for _, address := range epSubset.NotReadyAddresses {
at := getAddressType(address.IP) _, at := addressToEndpoint(address, true)
if at != nil && *at == addrType && len(expectedEndpoints) < maxEndpointsPerSubset { if at != nil && *at == addrType && len(expectedEndpoints) < maxEndpointsPerSubset {
expectedEndpoints[address.IP] = addressInfo{ expectedEndpoints[address.IP] = addressInfo{
ready: false, ready: false,

View File

@ -49,18 +49,6 @@ func (pk addrTypePortMapKey) addressType() discovery.AddressType {
return discovery.AddressTypeIPv4 return discovery.AddressTypeIPv4
} }
func getAddressType(address string) *discovery.AddressType {
ip := netutils.ParseIPSloppy(address)
if ip == nil {
return nil
}
addressType := discovery.AddressTypeIPv4
if ip.To4() == nil {
addressType = discovery.AddressTypeIPv6
}
return &addressType
}
// newEndpointSlice returns an EndpointSlice generated from an Endpoints // newEndpointSlice returns an EndpointSlice generated from an Endpoints
// resource, ports, and address type. // resource, ports, and address type.
func newEndpointSlice(endpoints *corev1.Endpoints, ports []discovery.EndpointPort, addrType discovery.AddressType, sliceName string) *discovery.EndpointSlice { func newEndpointSlice(endpoints *corev1.Endpoints, ports []discovery.EndpointPort, addrType discovery.AddressType, sliceName string) *discovery.EndpointSlice {
@ -115,10 +103,20 @@ func getEndpointSlicePrefix(serviceName string) string {
} }
// addressToEndpoint converts an address from an Endpoints resource to an // addressToEndpoint converts an address from an Endpoints resource to an
// EndpointSlice endpoint. // EndpointSlice endpoint and AddressType.
func addressToEndpoint(address corev1.EndpointAddress, ready bool) *discovery.Endpoint { func addressToEndpoint(address corev1.EndpointAddress, ready bool) (*discovery.Endpoint, *discovery.AddressType) {
ip := netutils.ParseIPSloppy(address.IP)
if ip == nil {
return nil, nil
}
addressType := discovery.AddressTypeIPv4
if ip.To4() == nil {
addressType = discovery.AddressTypeIPv6
}
endpoint := &discovery.Endpoint{ endpoint := &discovery.Endpoint{
Addresses: []string{address.IP}, // We parse and restringify the Endpoints IP in case it is in an irregular format.
Addresses: []string{ip.String()},
Conditions: discovery.EndpointConditions{ Conditions: discovery.EndpointConditions{
Ready: &ready, Ready: &ready,
}, },
@ -132,7 +130,7 @@ func addressToEndpoint(address corev1.EndpointAddress, ready bool) *discovery.En
endpoint.Hostname = &address.Hostname endpoint.Hostname = &address.Hostname
} }
return endpoint return endpoint, &addressType
} }
// epPortsToEpsPorts converts ports from an Endpoints resource to ports for an // epPortsToEpsPorts converts ports from an Endpoints resource to ports for an

View File

@ -217,8 +217,9 @@ func TestAddressToEndpoint(t *testing.T) {
NodeName: pointer.String("node-abc"), NodeName: pointer.String("node-abc"),
} }
ep := addressToEndpoint(epAddress, ready) ep, addrType := addressToEndpoint(epAddress, ready)
assert.EqualValues(t, expectedEndpoint, *ep) assert.EqualValues(t, expectedEndpoint, *ep)
assert.EqualValues(t, discovery.AddressTypeIPv4, *addrType)
} }
// Test helpers // Test helpers