...

Source file src/k8s.io/kubernetes/pkg/controller/endpointslicemirroring/reconciler_helpers.go

Documentation: k8s.io/kubernetes/pkg/controller/endpointslicemirroring

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package endpointslicemirroring
    18  
    19  import (
    20  	v1 "k8s.io/api/core/v1"
    21  	discovery "k8s.io/api/discovery/v1"
    22  	endpointsliceutil "k8s.io/endpointslice/util"
    23  )
    24  
    25  // slicesByAction includes lists of slices to create, update, or delete.
    26  type slicesByAction struct {
    27  	toCreate, toUpdate, toDelete []*discovery.EndpointSlice
    28  }
    29  
    30  // append appends slices from another slicesByAction struct.
    31  func (s *slicesByAction) append(slices slicesByAction) {
    32  	s.toCreate = append(s.toCreate, slices.toCreate...)
    33  	s.toUpdate = append(s.toUpdate, slices.toUpdate...)
    34  	s.toDelete = append(s.toDelete, slices.toDelete...)
    35  }
    36  
    37  // totalsByAction includes total numbers for added and removed.
    38  type totalsByAction struct {
    39  	added, updated, removed int
    40  }
    41  
    42  // add adds totals from another totalsByAction struct.
    43  func (t *totalsByAction) add(totals totalsByAction) {
    44  	t.added += totals.added
    45  	t.updated += totals.updated
    46  	t.removed += totals.removed
    47  }
    48  
    49  // newDesiredCalc initializes and returns a new desiredCalc.
    50  func newDesiredCalc() *desiredCalc {
    51  	return &desiredCalc{
    52  		portsByKey:          map[addrTypePortMapKey][]discovery.EndpointPort{},
    53  		endpointsByKey:      map[addrTypePortMapKey]endpointsliceutil.EndpointSet{},
    54  		numDesiredEndpoints: 0,
    55  	}
    56  }
    57  
    58  // desiredCalc helps calculate desired endpoints and ports.
    59  type desiredCalc struct {
    60  	portsByKey          map[addrTypePortMapKey][]discovery.EndpointPort
    61  	endpointsByKey      map[addrTypePortMapKey]endpointsliceutil.EndpointSet
    62  	numDesiredEndpoints int
    63  }
    64  
    65  // multiAddrTypePortMapKey stores addrTypePortMapKey for different address
    66  // types.
    67  type multiAddrTypePortMapKey map[discovery.AddressType]addrTypePortMapKey
    68  
    69  // initPorts initializes ports for a subset and address type and returns the
    70  // corresponding addrTypePortMapKey.
    71  func (d *desiredCalc) initPorts(subsetPorts []v1.EndpointPort) multiAddrTypePortMapKey {
    72  	endpointPorts := epPortsToEpsPorts(subsetPorts)
    73  	addrTypes := []discovery.AddressType{discovery.AddressTypeIPv4, discovery.AddressTypeIPv6}
    74  	multiKey := multiAddrTypePortMapKey{}
    75  
    76  	for _, addrType := range addrTypes {
    77  		multiKey[addrType] = newAddrTypePortMapKey(endpointPorts, addrType)
    78  		if _, ok := d.endpointsByKey[multiKey[addrType]]; !ok {
    79  			d.endpointsByKey[multiKey[addrType]] = endpointsliceutil.EndpointSet{}
    80  		}
    81  		d.portsByKey[multiKey[addrType]] = endpointPorts
    82  	}
    83  
    84  	return multiKey
    85  }
    86  
    87  // addAddress adds an EndpointAddress to the desired state if it is valid. It
    88  // returns false if the address was invalid.
    89  func (d *desiredCalc) addAddress(address v1.EndpointAddress, multiKey multiAddrTypePortMapKey, ready bool) bool {
    90  	endpoint := addressToEndpoint(address, ready)
    91  	addrType := getAddressType(address.IP)
    92  	if addrType == nil {
    93  		return false
    94  	}
    95  
    96  	d.endpointsByKey[multiKey[*addrType]].Insert(endpoint)
    97  	d.numDesiredEndpoints++
    98  	return true
    99  }
   100  
   101  type slicesByAddrType map[discovery.AddressType][]*discovery.EndpointSlice
   102  
   103  // recycleSlices will recycle the slices marked for deletion by replacing
   104  // creates with updates of slices that would otherwise be deleted.
   105  func recycleSlices(slices *slicesByAction) {
   106  	toCreateByAddrType := toSlicesByAddrType(slices.toCreate)
   107  	toDeleteByAddrType := toSlicesByAddrType(slices.toDelete)
   108  
   109  	for addrType, slicesToCreate := range toCreateByAddrType {
   110  		slicesToDelete := toDeleteByAddrType[addrType]
   111  		for i := 0; len(slicesToCreate) > i && len(slicesToDelete) > i; i++ {
   112  			slices.toCreate = removeSlice(slices.toCreate, slicesToCreate[i])
   113  			slices.toDelete = removeSlice(slices.toDelete, slicesToDelete[i])
   114  			slice := slicesToCreate[i]
   115  			slice.Name = slicesToDelete[i].Name
   116  			slices.toUpdate = append(slices.toUpdate, slice)
   117  		}
   118  	}
   119  }
   120  
   121  // removeSlice removes an EndpointSlice from a list of EndpointSlices.
   122  func removeSlice(slices []*discovery.EndpointSlice, sliceToRemove *discovery.EndpointSlice) []*discovery.EndpointSlice {
   123  	for i, slice := range slices {
   124  		if slice.Name == sliceToRemove.Name {
   125  			return append(slices[:i], slices[i+1:]...)
   126  		}
   127  	}
   128  	return slices
   129  }
   130  
   131  // toSliceByAddrType returns lists of EndpointSlices grouped by address.
   132  func toSlicesByAddrType(slices []*discovery.EndpointSlice) slicesByAddrType {
   133  	byAddrType := slicesByAddrType{}
   134  	for _, slice := range slices {
   135  		byAddrType[slice.AddressType] = append(byAddrType[slice.AddressType], slice)
   136  	}
   137  	return byAddrType
   138  }
   139  

View as plain text