in cni/network/invoker_azure.go [49:133]
func (invoker *AzureIPAMInvoker) Add(addConfig IPAMAddConfig) (IPAMAddResult, error) {
addResult := IPAMAddResult{interfaceInfo: make(map[string]network.InterfaceInfo)}
if addConfig.nwCfg == nil {
return addResult, invoker.plugin.Errorf("nil nwCfg passed to CNI ADD, stack: %+v", string(debug.Stack()))
}
if len(invoker.nwInfo.Subnets) > 0 {
addConfig.nwCfg.IPAM.Subnet = invoker.nwInfo.Subnets[0].Prefix.String()
}
// Call into IPAM plugin to allocate an address pool for the network.
result, err := invoker.plugin.DelegateAdd(addConfig.nwCfg.IPAM.Type, addConfig.nwCfg)
if err != nil && strings.Contains(err.Error(), ipam.ErrNoAvailableAddressPools.Error()) {
invoker.deleteIpamState()
logger.Info("Retry pool allocation after deleting IPAM state")
result, err = invoker.plugin.DelegateAdd(addConfig.nwCfg.IPAM.Type, addConfig.nwCfg)
}
if err != nil {
err = invoker.plugin.Errorf("Failed to allocate pool: %v", err)
return addResult, err
}
defer func() {
if err != nil {
if len(addResult.interfaceInfo) > 0 && len(addResult.interfaceInfo[invoker.getInterfaceInfoKey(cns.InfraNIC)].IPConfigs) > 0 {
if er := invoker.Delete(&addResult.interfaceInfo[invoker.getInterfaceInfoKey(cns.InfraNIC)].IPConfigs[0].Address, addConfig.nwCfg, nil, addConfig.options); er != nil {
err = invoker.plugin.Errorf("Failed to clean up IP's during Delete with error %v, after Add failed with error %w", er, err)
}
} else {
err = fmt.Errorf("No IP's to delete on error: %v", err)
}
}
}()
if addConfig.nwCfg.IPV6Mode != "" {
nwCfg6 := *addConfig.nwCfg
nwCfg6.IPAM.Environment = common.OptEnvironmentIPv6NodeIpam
nwCfg6.IPAM.Type = ipamV6
if len(invoker.nwInfo.Subnets) > 1 {
// ipv6 is the second subnet of the slice
nwCfg6.IPAM.Subnet = invoker.nwInfo.Subnets[1].Prefix.String()
}
var ipv6Result *cniTypesCurr.Result
ipv6Result, err = invoker.plugin.DelegateAdd(nwCfg6.IPAM.Type, &nwCfg6)
if err != nil {
err = invoker.plugin.Errorf("Failed to allocate v6 pool: %v", err)
} else {
result.IPs = append(result.IPs, ipv6Result.IPs...)
result.Routes = append(result.Routes, ipv6Result.Routes...)
addResult.ipv6Enabled = true
}
}
ipconfigs := make([]*network.IPConfig, len(result.IPs))
for i, ipconfig := range result.IPs {
ipconfigs[i] = &network.IPConfig{Address: ipconfig.Address, Gateway: ipconfig.Gateway}
}
routes := make([]network.RouteInfo, len(result.Routes))
for i, route := range result.Routes {
routes[i] = network.RouteInfo{Dst: route.Dst, Gw: route.GW}
}
// TODO: changed how host subnet prefix populated (check)
hostSubnetPrefix := net.IPNet{}
if len(result.IPs) > 0 {
hostSubnetPrefix = result.IPs[0].Address
}
addResult.interfaceInfo[invoker.getInterfaceInfoKey(cns.InfraNIC)] = network.InterfaceInfo{
IPConfigs: ipconfigs,
Routes: routes,
DNS: network.DNSInfo{
Suffix: result.DNS.Domain,
Servers: result.DNS.Nameservers,
},
NICType: cns.InfraNIC,
HostSubnetPrefix: hostSubnetPrefix,
}
return addResult, err
}