@@ -995,38 +995,85 @@ func (service *HTTPRestService) AssignAvailableIPConfigs(podInfo cns.PodInfo) ([
995995 if numOfNCs == 0 {
996996 return nil , ErrNoNCs
997997 }
998+
999+ // Map used to get the number of IPFamilies across all NCs
1000+ ncIPFamilies := map [cns.IPFamily ]struct {}{}
1001+ // Gets the IPFamilies from all NCs and store them in a map. This will be used to determine the number of IPs to return
1002+ for ncID := range service .state .ContainerStatus {
1003+ if len (ncIPFamilies ) == 2 {
1004+ break
1005+ }
1006+
1007+ for _ , secIPConfig := range service .state .ContainerStatus [ncID ].CreateNetworkContainerRequest .SecondaryIPConfigs {
1008+ if len (ncIPFamilies ) == 2 {
1009+ break
1010+ }
1011+
1012+ ip := net .ParseIP (secIPConfig .IPAddress )
1013+ if ip == nil {
1014+ continue
1015+ }
1016+
1017+ if ip .To4 () != nil {
1018+ ncIPFamilies [cns .IPv4 ] = struct {}{}
1019+ } else {
1020+ ncIPFamilies [cns .IPv6 ] = struct {}{}
1021+ }
1022+ }
1023+ }
1024+ // Makes sure we have at least one IPFamily across all NCs
1025+ numOfIPFamilies := len (ncIPFamilies )
1026+
1027+ numberOfIPs := numOfNCs
1028+ if numOfIPFamilies != 0 {
1029+ numberOfIPs = numOfIPFamilies
1030+ }
1031+
9981032 service .Lock ()
9991033 defer service .Unlock ()
10001034 // Creates a slice of PodIpInfo with the size as number of NCs to hold the result for assigned IP configs
1001- podIPInfo := make ([]cns.PodIpInfo , numOfNCs )
1035+ podIPInfo := make ([]cns.PodIpInfo , numberOfIPs )
10021036 // This map is used to store whether or not we have found an available IP from an NC when looping through the pool
10031037 ipsToAssign := make (map [string ]cns.IPConfigurationStatus )
10041038
10051039 // Searches for available IPs in the pool
10061040 for _ , ipState := range service .PodIPConfigState {
1007- // check if an IP from this NC is already set side for assignment.
1008- if _ , ncAlreadyMarkedForAssignment := ipsToAssign [ipState .NCID ]; ncAlreadyMarkedForAssignment {
1041+
1042+ // get the IPFamily of the current ipState
1043+ var ipStateFamily cns.IPFamily
1044+ if net .ParseIP (ipState .IPAddress ).To4 () != nil {
1045+ ipStateFamily = cns .IPv4
1046+ } else {
1047+ ipStateFamily = cns .IPv6
1048+ }
1049+
1050+ key := generateAssignedIPKey (ipState .NCID , ipStateFamily )
1051+
1052+ // check if the IP with the same family type exists already
1053+ if _ , ncIPFamilyAlreadyMarkedForAssignment := ipsToAssign [key ]; ncIPFamilyAlreadyMarkedForAssignment {
10091054 continue
10101055 }
10111056 // Checks if the current IP is available
10121057 if ipState .GetState () != types .Available {
10131058 continue
10141059 }
1015- ipsToAssign [ipState . NCID ] = ipState
1016- // Once one IP per container is found break out of the loop and stop searching
1017- if len (ipsToAssign ) == numOfNCs {
1060+ ipsToAssign [key ] = ipState
1061+ // Once numberOfIPs per container is found break out of the loop and stop searching
1062+ if len (ipsToAssign ) == numberOfIPs {
10181063 break
10191064 }
10201065 }
10211066
1022- // Checks to make sure we found one IP for each NC
1023- if len (ipsToAssign ) != numOfNCs {
1067+ // Checks to make sure we found one IP for each NCxIPFamily
1068+ if len (ipsToAssign ) != numberOfIPs {
10241069 for ncID := range service .state .ContainerStatus {
1025- if _ , found := ipsToAssign [ncID ]; found {
1026- continue
1070+ for ipFamily := range ncIPFamilies {
1071+ if _ , found := ipsToAssign [generateAssignedIPKey (ncID , ipFamily )]; found {
1072+ continue
1073+ }
1074+ return podIPInfo , errors .Errorf ("not enough IPs available of type %s for %s, waiting on Azure CNS to allocate more with NC Status: %s" ,
1075+ ipFamily , ncID , string (service .state .ContainerStatus [ncID ].CreateNetworkContainerRequest .NCStatus ))
10271076 }
1028- return podIPInfo , errors .Errorf ("not enough IPs available for %s, waiting on Azure CNS to allocate more with NC Status: %s" ,
1029- ncID , string (service .state .ContainerStatus [ncID ].CreateNetworkContainerRequest .NCStatus ))
10301077 }
10311078 }
10321079
@@ -1061,10 +1108,14 @@ func (service *HTTPRestService) AssignAvailableIPConfigs(podInfo cns.PodInfo) ([
10611108 return podIPInfo , fmt .Errorf ("not enough IPs available, waiting on Azure CNS to allocate more" )
10621109 }
10631110
1064- logger .Printf ("[AssignDesiredIPConfigs ] Successfully assigned IPs for pod %+v" , podInfo )
1111+ logger .Printf ("[AssignAvailableIPConfigs ] Successfully assigned IPs for pod %+v" , podInfo )
10651112 return podIPInfo , nil
10661113}
10671114
1115+ func generateAssignedIPKey (ncID string , ipFamily cns.IPFamily ) string {
1116+ return fmt .Sprintf ("%s_%s" , ncID , string (ipFamily ))
1117+ }
1118+
10681119// If IPConfigs are already assigned to the pod, it returns that else it returns the available ipconfigs.
10691120func requestIPConfigsHelper (service * HTTPRestService , req cns.IPConfigsRequest ) ([]cns.PodIpInfo , error ) {
10701121 // check if ipconfigs already assigned to this pod and return if exists or error
0 commit comments