|
25 | 25 | ErrStoreEmpty = errors.New("empty endpoint state store") |
26 | 26 | ErrParsePodIPFailed = errors.New("failed to parse pod's ip") |
27 | 27 | ErrNoNCs = errors.New("no NCs found in the CNS internal state") |
| 28 | + ErrNoIPFamilies = errors.New("No IP Families found on NCs") |
28 | 29 | ErrOptManageEndpointState = errors.New("CNS is not set to manage the endpoint state") |
29 | 30 | ErrEndpointStateNotFound = errors.New("endpoint state could not be found in the statefile") |
30 | 31 | ErrGetAllNCResponseEmpty = errors.New("failed to get NC responses from statefile") |
@@ -989,44 +990,69 @@ func (service *HTTPRestService) AssignDesiredIPConfigs(podInfo cns.PodInfo, desi |
989 | 990 | // Assigns an available IP from each NC on the NNC. If there is one NC then we expect to only have one IP return |
990 | 991 | // In the case of dualstack we would expect to have one IPv6 from one NC and one IPv4 from a second NC |
991 | 992 | func (service *HTTPRestService) AssignAvailableIPConfigs(podInfo cns.PodInfo) ([]cns.PodIpInfo, error) { |
992 | | - // Gets the number of NCs which will determine the number of IPs given to a pod |
993 | | - numOfNCs := len(service.state.ContainerStatus) |
994 | | - // if there are no NCs on the NNC there will be no IPs in the pool so return error |
995 | | - if numOfNCs == 0 { |
| 993 | + // Map used to get the number of IPFamilies across all NCs |
| 994 | + ipFamilies := map[cns.IPFamily]struct{}{} |
| 995 | + |
| 996 | + // checks to make sure we have at least one NC |
| 997 | + if len(service.state.ContainerStatus) == 0 { |
996 | 998 | return nil, ErrNoNCs |
997 | 999 | } |
| 1000 | + |
| 1001 | + // Gets the IPFamilies from all NCs and stores them in a map. This will be ued to determine the amount of IPs to return |
| 1002 | + for ncID := range service.state.ContainerStatus { |
| 1003 | + for ipFamily := range service.state.ContainerStatus[ncID].CreateNetworkContainerRequest.IPFamilies { |
| 1004 | + ipFamilies[ipFamily] = struct{}{} |
| 1005 | + } |
| 1006 | + } |
| 1007 | + |
| 1008 | + // Makes sure we have at least one IPFamily across all NCs |
| 1009 | + numOfIPFamilies := len(ipFamilies) |
| 1010 | + if numOfIPFamilies == 0 { |
| 1011 | + return nil, ErrNoIPFamilies |
| 1012 | + } |
| 1013 | + |
998 | 1014 | service.Lock() |
999 | 1015 | defer service.Unlock() |
1000 | 1016 | // 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) |
| 1017 | + podIPInfo := make([]cns.PodIpInfo, numOfIPFamilies) |
1002 | 1018 | // This map is used to store whether or not we have found an available IP from an NC when looping through the pool |
1003 | | - ipsToAssign := make(map[string]cns.IPConfigurationStatus) |
| 1019 | + ipsToAssign := make(map[cns.IPFamily]cns.IPConfigurationStatus) |
1004 | 1020 |
|
1005 | 1021 | // Searches for available IPs in the pool |
1006 | 1022 | 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 { |
| 1023 | + // get the IPFamily of the current ipState |
| 1024 | + var ipStateFamily cns.IPFamily |
| 1025 | + if net.ParseIP(ipState.IPAddress).To4() != nil { |
| 1026 | + ipStateFamily = cns.IPv4Family |
| 1027 | + } else { |
| 1028 | + ipStateFamily = cns.IPv6Family |
| 1029 | + } |
| 1030 | + |
| 1031 | + // check if the IP with the same family type exists already |
| 1032 | + if _, IPFamilyAlreadyMarkedForAssignment := ipsToAssign[ipStateFamily]; IPFamilyAlreadyMarkedForAssignment { |
1009 | 1033 | continue |
1010 | 1034 | } |
1011 | 1035 | // Checks if the current IP is available |
1012 | 1036 | if ipState.GetState() != types.Available { |
1013 | 1037 | continue |
1014 | 1038 | } |
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 { |
| 1039 | + ipsToAssign[ipStateFamily] = ipState |
| 1040 | + // Once one IP per family is found break out of the loop and stop searching |
| 1041 | + if len(ipsToAssign) == numOfIPFamilies { |
1018 | 1042 | break |
1019 | 1043 | } |
1020 | 1044 | } |
1021 | 1045 |
|
1022 | | - // Checks to make sure we found one IP for each NC |
1023 | | - if len(ipsToAssign) != numOfNCs { |
| 1046 | + // Checks to make sure we found one IP for each IPFamily |
| 1047 | + if len(ipsToAssign) != numOfIPFamilies { |
1024 | 1048 | for ncID := range service.state.ContainerStatus { |
1025 | | - if _, found := ipsToAssign[ncID]; found { |
1026 | | - continue |
| 1049 | + for ipFamily := range service.state.ContainerStatus[ncID].CreateNetworkContainerRequest.IPFamilies { |
| 1050 | + if _, found := ipsToAssign[ipFamily]; found { |
| 1051 | + continue |
| 1052 | + } |
| 1053 | + return podIPInfo, errors.Errorf("not enough IPs available of type %s for %s, waiting on Azure CNS to allocate more with NC Status: %s", |
| 1054 | + ipFamily, ncID, string(service.state.ContainerStatus[ncID].CreateNetworkContainerRequest.NCStatus)) |
1027 | 1055 | } |
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)) |
1030 | 1056 | } |
1031 | 1057 | } |
1032 | 1058 |
|
|
0 commit comments