in pkg/pool/pool.go [637:722]
func (p *pool) getPDDeviation() int {
deviationPrefix := 0
var isWarmIPTargetDefined, isMinIPTargetDefined, isWarmPrefixTargetDefined bool
// if DesiredSize is 0, it means PD pool is in draining state, then set targets to 0
if p.warmPoolConfig.DesiredSize == 0 {
p.warmPoolConfig.WarmIPTarget = 0
p.warmPoolConfig.MinIPTarget = 0
p.warmPoolConfig.WarmPrefixTarget = 0
} else {
// PD pool is active, check if target values are valid. If so, set defined flag to true
if p.warmPoolConfig.WarmIPTarget > 0 {
isWarmIPTargetDefined = true
}
if p.warmPoolConfig.MinIPTarget > 0 {
isMinIPTargetDefined = true
}
if p.warmPoolConfig.WarmPrefixTarget > 0 {
isWarmPrefixTargetDefined = true
}
// set target to default values if not defined
if !isWarmIPTargetDefined {
if isMinIPTargetDefined || !isWarmPrefixTargetDefined {
p.warmPoolConfig.WarmIPTarget = config.IPv4PDDefaultWarmIPTargetSize
}
}
if !isMinIPTargetDefined {
if isWarmIPTargetDefined || !isWarmPrefixTargetDefined {
p.warmPoolConfig.MinIPTarget = config.IPv4PDDefaultMinIPTargetSize
}
}
}
numExistingWarmResources := numResourcesFromMap(p.warmResources)
freePrefixes := findFreeGroup(p.warmResources, NumIPv4AddrPerPrefix)
// if neither WarmIPTarget nor MinIPTarget defined but WarmPrefixTarget is defined, return deviation needed for warm prefix target
if !isWarmIPTargetDefined && !isMinIPTargetDefined && isWarmPrefixTargetDefined {
deviationPrefix = p.warmPoolConfig.WarmPrefixTarget - len(freePrefixes) - utils.CeilDivision(p.pendingCreate, NumIPv4AddrPerPrefix)
if deviationPrefix != 0 {
p.log.Info("calculating IP deviation for prefix pool to satisfy warm prefix target", "warm prefix target",
p.warmPoolConfig.WarmPrefixTarget, "numFreePrefix", len(freePrefixes), "p.pendingCreate", p.pendingCreate,
"p.pendingDelete", p.pendingDelete, "deviation", deviationPrefix*NumIPv4AddrPerPrefix)
}
return deviationPrefix * NumIPv4AddrPerPrefix
}
// total resources in pool include used resources, warm resources, pendingCreate (to avoid duplicate request), and coolDownQueue
numTotalResources := len(p.usedResources) + p.pendingCreate + numExistingWarmResources + len(p.coolDownQueue)
// number of existing prefixes
numCurrPrefix := utils.CeilDivision(numTotalResources, 16)
// number of total resources required to meet WarmIPTarget
numTotalResForWarmIPTarget := len(p.usedResources) + p.warmPoolConfig.WarmIPTarget
// number of total prefixes required to meet WarmIPTarget
numPrefixForWarmIPTarget := utils.CeilDivision(numTotalResForWarmIPTarget, 16)
// number of prefixes to meet MinIPTarget
numPrefixForMinIPTarget := utils.CeilDivision(p.warmPoolConfig.MinIPTarget, 16)
if numPrefixForWarmIPTarget >= numPrefixForMinIPTarget {
// difference is the number of prefixes to create or delete
deviationPrefix = numPrefixForWarmIPTarget - numCurrPrefix
} else {
// difference is the number of prefixes to create in order to meet MinIPTarget
deviationPrefix = numPrefixForMinIPTarget - numCurrPrefix
}
// if we need to delete prefixes, should check if any prefix is free to be deleted since they can be fragmented. If not, reset deviation
if deviationPrefix < 0 && len(freePrefixes) == 0 {
deviationPrefix = 0
}
if deviationPrefix != 0 {
p.log.V(1).Info("calculating IP deviation for prefix pool", "warmPoolConfig", p.warmPoolConfig,
"used resources", len(p.usedResources), "existing warm resources", numExistingWarmResources, "pendingCreate", p.pendingCreate,
"pendingDelete", p.pendingDelete, "numTotalResources", numTotalResources, "numCurrPrefix", numCurrPrefix,
"numTotalResForWarmIPTarget", numTotalResForWarmIPTarget, "numPrefixForWarmIPTarget", numPrefixForWarmIPTarget,
"numPrefixForMinIPTarget", numPrefixForMinIPTarget, "deviation", deviationPrefix*NumIPv4AddrPerPrefix)
}
return deviationPrefix * NumIPv4AddrPerPrefix
}