|
27 | 27 | ErrNoNCs = errors.New("no NCs found in the CNS internal state") |
28 | 28 | ErrOptManageEndpointState = errors.New("CNS is not set to manage the endpoint state") |
29 | 29 | ErrEndpointStateNotFound = errors.New("endpoint state could not be found in the statefile") |
| 30 | + ErrGetAllNCResponseEmpty = errors.New("failed to get NC responses from statefile") |
30 | 31 | ) |
31 | 32 |
|
32 | 33 | const ( |
@@ -113,6 +114,81 @@ func (service *HTTPRestService) requestIPConfigHandlerHelper(ctx context.Context |
113 | 114 | }, nil |
114 | 115 | } |
115 | 116 |
|
| 117 | +// requestIPConfigHandlerHelperStandalone validates the request, assign IPs and return the IPConfigs |
| 118 | +func (service *HTTPRestService) requestIPConfigHandlerHelperStandalone(ctx context.Context, ipconfigsRequest cns.IPConfigsRequest) (*cns.IPConfigsResponse, error) { |
| 119 | + // For SWIFT v2 scenario, the validator function will also modify the ipconfigsRequest. |
| 120 | + podInfo, returnCode, returnMessage := service.validateIPConfigsRequest(ctx, ipconfigsRequest) |
| 121 | + if returnCode != types.Success { |
| 122 | + return &cns.IPConfigsResponse{ |
| 123 | + Response: cns.Response{ |
| 124 | + ReturnCode: returnCode, |
| 125 | + Message: returnMessage, |
| 126 | + }, |
| 127 | + }, errors.New("failed to validate ip config request or unmarshal orchestratorContext") |
| 128 | + } |
| 129 | + |
| 130 | + orchestratorContext, err := podInfo.OrchestratorContext() |
| 131 | + if err != nil { |
| 132 | + return &cns.IPConfigsResponse{}, fmt.Errorf("error getting orchestrator context from PodInfo %w", err) |
| 133 | + } |
| 134 | + cnsRequest := cns.GetNetworkContainerRequest{OrchestratorContext: orchestratorContext} |
| 135 | + resp := service.getAllNetworkContainerResponses(cnsRequest) //nolint:contextcheck // not passed in any methods, appease linter |
| 136 | + // return err if returned list has no NCs |
| 137 | + if len(resp) == 0 { |
| 138 | + return &cns.IPConfigsResponse{ |
| 139 | + Response: cns.Response{ |
| 140 | + ReturnCode: types.FailedToAllocateIPConfig, |
| 141 | + Message: fmt.Sprintf("AllocateIPConfig failed due to not getting NC Response from statefile, IP config request is %v", ipconfigsRequest), |
| 142 | + }, |
| 143 | + }, ErrGetAllNCResponseEmpty |
| 144 | + } |
| 145 | + |
| 146 | + podIPInfoList := make([]cns.PodIpInfo, 0, len(resp)) |
| 147 | + for i := range resp { |
| 148 | + podIPInfo := cns.PodIpInfo{ |
| 149 | + PodIPConfig: resp[i].IPConfiguration.IPSubnet, |
| 150 | + MacAddress: resp[i].NetworkInterfaceInfo.MACAddress, |
| 151 | + NICType: resp[i].NetworkInterfaceInfo.NICType, |
| 152 | + NetworkContainerPrimaryIPConfig: resp[i].IPConfiguration, |
| 153 | + } |
| 154 | + podIPInfoList = append(podIPInfoList, podIPInfo) |
| 155 | + } |
| 156 | + |
| 157 | + ipConfigsResp := &cns.IPConfigsResponse{ |
| 158 | + Response: cns.Response{ |
| 159 | + ReturnCode: types.Success, |
| 160 | + }, |
| 161 | + PodIPInfo: podIPInfoList, |
| 162 | + } |
| 163 | + |
| 164 | + err = service.updatePodInfoWithInterfaces(ctx, ipConfigsResp) |
| 165 | + if err != nil { |
| 166 | + return &cns.IPConfigsResponse{ |
| 167 | + Response: cns.Response{ |
| 168 | + ReturnCode: types.FailedToAllocateIPConfig, |
| 169 | + Message: fmt.Sprintf("AllocateIPConfig failed while updating pod with interfaces: %v, IP config request is %v", err, ipconfigsRequest), |
| 170 | + }, |
| 171 | + }, err |
| 172 | + } |
| 173 | + return ipConfigsResp, nil |
| 174 | +} |
| 175 | + |
| 176 | +func (service *HTTPRestService) updatePodInfoWithInterfaces(ctx context.Context, ipconfigResponse *cns.IPConfigsResponse) error { |
| 177 | + // fetching primary host interface to use below for updating IPConfigsResponse |
| 178 | + hostPrimaryInterface, err := service.getPrimaryHostInterface(ctx) |
| 179 | + if err != nil { |
| 180 | + return err |
| 181 | + } |
| 182 | + for i := range ipconfigResponse.PodIPInfo { |
| 183 | + ipconfigResponse.PodIPInfo[i].HostPrimaryIPInfo = cns.HostIPInfo{ |
| 184 | + Gateway: hostPrimaryInterface.Gateway, |
| 185 | + PrimaryIP: hostPrimaryInterface.PrimaryIP, |
| 186 | + Subnet: hostPrimaryInterface.Subnet, |
| 187 | + } |
| 188 | + } |
| 189 | + return nil |
| 190 | +} |
| 191 | + |
116 | 192 | // RequestIPConfigHandler requests an IPConfig from the CNS state |
117 | 193 | func (service *HTTPRestService) RequestIPConfigHandler(w http.ResponseWriter, r *http.Request) { |
118 | 194 | var ipconfigRequest cns.IPConfigRequest |
@@ -201,8 +277,16 @@ func (service *HTTPRestService) RequestIPConfigsHandler(w http.ResponseWriter, r |
201 | 277 |
|
202 | 278 | // Check if IPConfigsHandlerMiddleware is set |
203 | 279 | if service.IPConfigsHandlerMiddleware != nil { |
204 | | - // Wrap the default datapath handlers with the middleware |
205 | | - wrappedHandler := service.IPConfigsHandlerMiddleware.IPConfigsRequestHandlerWrapper(service.requestIPConfigHandlerHelper, service.ReleaseIPConfigHandlerHelper) |
| 280 | + // Wrap the default datapath handlers with the middleware depending on middleware type |
| 281 | + var wrappedHandler cns.IPConfigsHandlerFunc |
| 282 | + switch service.IPConfigsHandlerMiddleware.Type() { |
| 283 | + case cns.K8sSWIFTV2: |
| 284 | + wrappedHandler = service.IPConfigsHandlerMiddleware.IPConfigsRequestHandlerWrapper(service.requestIPConfigHandlerHelper, service.ReleaseIPConfigHandlerHelper) |
| 285 | + // this middleware is used for standalone swiftv2 secenario where a different helper is invoked as the PodInfo is read from cns state |
| 286 | + case cns.StandaloneSWIFTV2: |
| 287 | + wrappedHandler = service.IPConfigsHandlerMiddleware.IPConfigsRequestHandlerWrapper(service.requestIPConfigHandlerHelperStandalone, nil) |
| 288 | + } |
| 289 | + |
206 | 290 | ipConfigsResp, err = wrappedHandler(r.Context(), ipconfigsRequest) |
207 | 291 | } else { |
208 | 292 | ipConfigsResp, err = service.requestIPConfigHandlerHelper(r.Context(), ipconfigsRequest) // nolint:contextcheck // appease linter |
|
0 commit comments