@@ -995,38 +995,87 @@ 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+ ipFamilies := map [cns.IPFamily ]struct {}{}
1001+
1002+ // Gets the IPFamilies from all NCs and store them in a map. This will be used to determine the number of IPs to return
1003+ for ncID := range service .state .ContainerStatus {
1004+ if len (ipFamilies ) == 2 {
1005+ break
1006+ }
1007+
1008+ for _ , secIPConfig := range service .state .ContainerStatus [ncID ].CreateNetworkContainerRequest .SecondaryIPConfigs {
1009+ if len (ipFamilies ) == 2 {
1010+ break
1011+ }
1012+
1013+ ip := net .ParseIP (secIPConfig .IPAddress )
1014+ if ip == nil {
1015+ continue
1016+ }
1017+
1018+ if ip .To4 () != nil {
1019+ ipFamilies [cns .IPv4Family ] = struct {}{}
1020+ } else {
1021+ ipFamilies [cns .IPv6Family ] = struct {}{}
1022+ }
1023+ }
1024+ }
1025+
1026+ // Makes sure we have at least one IPFamily across all NCs
1027+ numOfIPFamilies := len (ipFamilies )
1028+
1029+ numberOfIPs := numOfNCs
1030+ if numOfIPFamilies != 0 {
1031+ numberOfIPs = numOfIPFamilies
1032+ }
1033+
9981034 service .Lock ()
9991035 defer service .Unlock ()
10001036 // 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 )
1037+ podIPInfo := make ([]cns.PodIpInfo , numberOfIPs )
10021038 // This map is used to store whether or not we have found an available IP from an NC when looping through the pool
10031039 ipsToAssign := make (map [string ]cns.IPConfigurationStatus )
10041040
10051041 // Searches for available IPs in the pool
10061042 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 {
1043+
1044+ // get the IPFamily of the current ipState
1045+ var ipStateFamily cns.IPFamily
1046+ if net .ParseIP (ipState .IPAddress ).To4 () != nil {
1047+ ipStateFamily = cns .IPv4Family
1048+ } else {
1049+ ipStateFamily = cns .IPv6Family
1050+ }
1051+
1052+ key := generateAssignedIPKey (ipState .NCID , ipStateFamily )
1053+
1054+ // check if the IP with the same family type exists already
1055+ if _ , ncIPFamilyAlreadyMarkedForAssignment := ipsToAssign [key ]; ncIPFamilyAlreadyMarkedForAssignment {
10091056 continue
10101057 }
10111058 // Checks if the current IP is available
10121059 if ipState .GetState () != types .Available {
10131060 continue
10141061 }
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 {
1062+ ipsToAssign [key ] = ipState
1063+ // Once numberOfIPs per container is found break out of the loop and stop searching
1064+ if len (ipsToAssign ) == numberOfIPs {
10181065 break
10191066 }
10201067 }
10211068
1022- // Checks to make sure we found one IP for each NC
1023- if len (ipsToAssign ) != numOfNCs {
1069+ // Checks to make sure we found one IP for each NCxIPFamily
1070+ if len (ipsToAssign ) != numberOfIPs {
10241071 for ncID := range service .state .ContainerStatus {
1025- if _ , found := ipsToAssign [ncID ]; found {
1026- continue
1072+ for ipFamily := range ipFamilies {
1073+ if _ , found := ipsToAssign [generateAssignedIPKey (ncID , ipFamily )]; found {
1074+ continue
1075+ }
1076+ return podIPInfo , errors .Errorf ("not enough IPs available of type %s for %s, waiting on Azure CNS to allocate more with NC Status: %s" ,
1077+ ipFamily , ncID , string (service .state .ContainerStatus [ncID ].CreateNetworkContainerRequest .NCStatus ))
10271078 }
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 ))
10301079 }
10311080 }
10321081
@@ -1061,10 +1110,14 @@ func (service *HTTPRestService) AssignAvailableIPConfigs(podInfo cns.PodInfo) ([
10611110 return podIPInfo , fmt .Errorf ("not enough IPs available, waiting on Azure CNS to allocate more" )
10621111 }
10631112
1064- logger .Printf ("[AssignDesiredIPConfigs ] Successfully assigned IPs for pod %+v" , podInfo )
1113+ logger .Printf ("[AssignAvailableIPConfigs ] Successfully assigned IPs for pod %+v" , podInfo )
10651114 return podIPInfo , nil
10661115}
10671116
1117+ func generateAssignedIPKey (ncID string , ipFamily cns.IPFamily ) string {
1118+ return fmt .Sprintf ("%s_%s" , ncID , string (ipFamily ))
1119+ }
1120+
10681121// If IPConfigs are already assigned to the pod, it returns that else it returns the available ipconfigs.
10691122func requestIPConfigsHelper (service * HTTPRestService , req cns.IPConfigsRequest ) ([]cns.PodIpInfo , error ) {
10701123 // check if ipconfigs already assigned to this pod and return if exists or error
0 commit comments