mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	migrate files: endpointset.go endpointslice_tracker.go endpointslice_tracker_test.go errors.go
		
			
				
	
	
		
			139 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2020 The Kubernetes Authors.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package endpointslicemirroring
 | 
						|
 | 
						|
import (
 | 
						|
	v1 "k8s.io/api/core/v1"
 | 
						|
	discovery "k8s.io/api/discovery/v1"
 | 
						|
	endpointsliceutil "k8s.io/kubernetes/pkg/controller/util/endpointslice"
 | 
						|
)
 | 
						|
 | 
						|
// slicesByAction includes lists of slices to create, update, or delete.
 | 
						|
type slicesByAction struct {
 | 
						|
	toCreate, toUpdate, toDelete []*discovery.EndpointSlice
 | 
						|
}
 | 
						|
 | 
						|
// append appends slices from another slicesByAction struct.
 | 
						|
func (s *slicesByAction) append(slices slicesByAction) {
 | 
						|
	s.toCreate = append(s.toCreate, slices.toCreate...)
 | 
						|
	s.toUpdate = append(s.toUpdate, slices.toUpdate...)
 | 
						|
	s.toDelete = append(s.toDelete, slices.toDelete...)
 | 
						|
}
 | 
						|
 | 
						|
// totalsByAction includes total numbers for added and removed.
 | 
						|
type totalsByAction struct {
 | 
						|
	added, updated, removed int
 | 
						|
}
 | 
						|
 | 
						|
// add adds totals from another totalsByAction struct.
 | 
						|
func (t *totalsByAction) add(totals totalsByAction) {
 | 
						|
	t.added += totals.added
 | 
						|
	t.updated += totals.updated
 | 
						|
	t.removed += totals.removed
 | 
						|
}
 | 
						|
 | 
						|
// newDesiredCalc initializes and returns a new desiredCalc.
 | 
						|
func newDesiredCalc() *desiredCalc {
 | 
						|
	return &desiredCalc{
 | 
						|
		portsByKey:          map[addrTypePortMapKey][]discovery.EndpointPort{},
 | 
						|
		endpointsByKey:      map[addrTypePortMapKey]endpointsliceutil.EndpointSet{},
 | 
						|
		numDesiredEndpoints: 0,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// desiredCalc helps calculate desired endpoints and ports.
 | 
						|
type desiredCalc struct {
 | 
						|
	portsByKey          map[addrTypePortMapKey][]discovery.EndpointPort
 | 
						|
	endpointsByKey      map[addrTypePortMapKey]endpointsliceutil.EndpointSet
 | 
						|
	numDesiredEndpoints int
 | 
						|
}
 | 
						|
 | 
						|
// multiAddrTypePortMapKey stores addrTypePortMapKey for different address
 | 
						|
// types.
 | 
						|
type multiAddrTypePortMapKey map[discovery.AddressType]addrTypePortMapKey
 | 
						|
 | 
						|
// initPorts initializes ports for a subset and address type and returns the
 | 
						|
// corresponding addrTypePortMapKey.
 | 
						|
func (d *desiredCalc) initPorts(subsetPorts []v1.EndpointPort) multiAddrTypePortMapKey {
 | 
						|
	endpointPorts := epPortsToEpsPorts(subsetPorts)
 | 
						|
	addrTypes := []discovery.AddressType{discovery.AddressTypeIPv4, discovery.AddressTypeIPv6}
 | 
						|
	multiKey := multiAddrTypePortMapKey{}
 | 
						|
 | 
						|
	for _, addrType := range addrTypes {
 | 
						|
		multiKey[addrType] = newAddrTypePortMapKey(endpointPorts, addrType)
 | 
						|
		if _, ok := d.endpointsByKey[multiKey[addrType]]; !ok {
 | 
						|
			d.endpointsByKey[multiKey[addrType]] = endpointsliceutil.EndpointSet{}
 | 
						|
		}
 | 
						|
		d.portsByKey[multiKey[addrType]] = endpointPorts
 | 
						|
	}
 | 
						|
 | 
						|
	return multiKey
 | 
						|
}
 | 
						|
 | 
						|
// addAddress adds an EndpointAddress to the desired state if it is valid. It
 | 
						|
// returns false if the address was invalid.
 | 
						|
func (d *desiredCalc) addAddress(address v1.EndpointAddress, multiKey multiAddrTypePortMapKey, ready bool) bool {
 | 
						|
	endpoint := addressToEndpoint(address, ready)
 | 
						|
	addrType := getAddressType(address.IP)
 | 
						|
	if addrType == nil {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
 | 
						|
	d.endpointsByKey[multiKey[*addrType]].Insert(endpoint)
 | 
						|
	d.numDesiredEndpoints++
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
type slicesByAddrType map[discovery.AddressType][]*discovery.EndpointSlice
 | 
						|
 | 
						|
// recycleSlices will recycle the slices marked for deletion by replacing
 | 
						|
// creates with updates of slices that would otherwise be deleted.
 | 
						|
func recycleSlices(slices *slicesByAction) {
 | 
						|
	toCreateByAddrType := toSlicesByAddrType(slices.toCreate)
 | 
						|
	toDeleteByAddrType := toSlicesByAddrType(slices.toDelete)
 | 
						|
 | 
						|
	for addrType, slicesToCreate := range toCreateByAddrType {
 | 
						|
		slicesToDelete := toDeleteByAddrType[addrType]
 | 
						|
		for i := 0; len(slicesToCreate) > i && len(slicesToDelete) > i; i++ {
 | 
						|
			slices.toCreate = removeSlice(slices.toCreate, slicesToCreate[i])
 | 
						|
			slices.toDelete = removeSlice(slices.toDelete, slicesToDelete[i])
 | 
						|
			slice := slicesToCreate[i]
 | 
						|
			slice.Name = slicesToDelete[i].Name
 | 
						|
			slices.toUpdate = append(slices.toUpdate, slice)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// removeSlice removes an EndpointSlice from a list of EndpointSlices.
 | 
						|
func removeSlice(slices []*discovery.EndpointSlice, sliceToRemove *discovery.EndpointSlice) []*discovery.EndpointSlice {
 | 
						|
	for i, slice := range slices {
 | 
						|
		if slice.Name == sliceToRemove.Name {
 | 
						|
			return append(slices[:i], slices[i+1:]...)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return slices
 | 
						|
}
 | 
						|
 | 
						|
// toSliceByAddrType returns lists of EndpointSlices grouped by address.
 | 
						|
func toSlicesByAddrType(slices []*discovery.EndpointSlice) slicesByAddrType {
 | 
						|
	byAddrType := slicesByAddrType{}
 | 
						|
	for _, slice := range slices {
 | 
						|
		byAddrType[slice.AddressType] = append(byAddrType[slice.AddressType], slice)
 | 
						|
	}
 | 
						|
	return byAddrType
 | 
						|
}
 |