Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions cns/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,38 @@ func (c *Client) UpdateEndpoint(ctx context.Context, endpointID string, ipInfo m

var response cns.Response
err = json.NewDecoder(res.Body).Decode(&response)
if err != nil {
return nil, errors.Wrap(err, "failed to decode CNS Response")
}

if response.ReturnCode != 0 {
return nil, errors.New(response.Message)
}

return &response, nil
}

func (c *Client) DeleteEndpointState(ctx context.Context, endpointID string) (*cns.Response, error) {
// build the request
u := c.routes[cns.EndpointAPI]
uString := u.String() + endpointID
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uString, http.NoBody)
if err != nil {
return nil, errors.Wrap(err, "failed to build request")
}
req.Header.Set(headerContentType, contentTypeJSON)
res, err := c.client.Do(req)
if err != nil {
return nil, &ConnectionFailureErr{cause: err}
}

defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, errors.Errorf("http response %d", res.StatusCode)
}

var response cns.Response
err = json.NewDecoder(res.Body).Decode(&response)
if err != nil {
return nil, errors.Wrap(err, "failed to decode CNS Response")
}
Expand Down
68 changes: 68 additions & 0 deletions cns/restserver/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,8 @@ func (service *HTTPRestService) EndpointHandlerAPI(w http.ResponseWriter, r *htt
service.GetEndpointHandler(w, r)
case http.MethodPatch:
service.UpdateEndpointHandler(w, r)
case http.MethodDelete:
service.DeleteEndpointStateHandler(w, r)
default:
logger.Errorf("[EndpointHandlerAPI] EndpointHandler API expect http Get or Patch method")
}
Expand Down Expand Up @@ -1393,3 +1395,69 @@ func (service *HTTPRestService) getIPFamiliesMap() map[cns.IPFamily]struct{} {
func (service *HTTPRestService) GetIPFamilyCount() int {
return len(service.getIPFamiliesMap())
}

func (service *HTTPRestService) DeleteEndpointStateHandler(w http.ResponseWriter, r *http.Request) {
opName := "DeleteEndpointStateHandler"
logger.Printf("[DeleteEndpointStateHandler] DeleteEndpointState for %s", r.URL.Path) //nolint:staticcheck // reason: using deprecated call until migration to new API
endpointID := strings.TrimPrefix(r.URL.Path, cns.EndpointPath)

if service.EndpointStateStore == nil {
response := cns.Response{
ReturnCode: types.UnexpectedError,
Message: "[DeleteEndpointStateHandler] EndpointStateStore is not initialized",
}
err := common.Encode(w, &response)
logger.Response(opName, response, response.ReturnCode, err) //nolint:staticcheck // reason: using deprecated call until migration to new API
return
}

// Decode the request body to get ipInfo if needed
var req map[string]*IPInfo
err := common.Decode(w, r, &req)
if err != nil {
logger.Printf("[DeleteEndpointStateHandler] Failed to decode request body: %v", err) //nolint:staticcheck // reason: using deprecated call until migration to new API
// Continue with deletion even if decode fails, as ipInfo might not be needed
}

Comment on lines +1414 to +1421
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code decodes a request body for a DELETE operation but then ignores any decode errors and doesn't use the decoded data. Since DELETE operations typically don't require a request body and the endpointID is extracted from the URL path, this decode logic should be removed.

Suggested change
// Decode the request body to get ipInfo if needed
var req map[string]*IPInfo
err := common.Decode(w, r, &req)
if err != nil {
logger.Printf("[DeleteEndpointStateHandler] Failed to decode request body: %v", err) //nolint:staticcheck // reason: using deprecated call until migration to new API
// Continue with deletion even if decode fails, as ipInfo might not be needed
}

Copilot uses AI. Check for mistakes.

// Delete the endpoint from state
err = service.DeleteEndpointStateHelper(endpointID)
if err != nil {
response := cns.Response{
ReturnCode: types.UnexpectedError,
Message: fmt.Sprintf("[DeleteEndpointStateHandler] Failed to delete endpoint state for %s with error: %s", endpointID, err.Error()),
}
err = common.Encode(w, &response)
logger.Response(opName, response, response.ReturnCode, err) //nolint:staticcheck // reason: using deprecated call until migration to new API
return
}

response := cns.Response{
ReturnCode: types.Success,
Message: "[DeleteEndpointStateHandler] Endpoint state deleted successfully",
}
err = common.Encode(w, &response)
logger.Response(opName, response, response.ReturnCode, err) //nolint:staticcheck // reason: using deprecated call until migration to new API
}

func (service *HTTPRestService) DeleteEndpointStateHelper(endpointID string) error {
if service.EndpointStateStore == nil {
return ErrStoreEmpty
}
logger.Printf("[deleteEndpointState] Deleting Endpoint state from state file %s", endpointID) //nolint:staticcheck // reason: using deprecated call until migration to new API
_, endpointExist := service.EndpointState[endpointID]
if !endpointExist {
logger.Printf("[deleteEndpointState] endpoint could not be found in the statefile %s", endpointID) //nolint:staticcheck // reason: using deprecated call until migration to new API
return fmt.Errorf("[deleteEndpointState] endpoint %s: %w", endpointID, ErrEndpointStateNotFound)
}

// Delete the endpoint from the state
delete(service.EndpointState, endpointID)

// Write the updated state back to the store
err := service.EndpointStateStore.Write(EndpointStoreKey, service.EndpointState)
if err != nil {
return fmt.Errorf("[deleteEndpointState] failed to write endpoint state to store: %w", err)
}
logger.Printf("[deleteEndpointState] successfully deleted endpoint %s from state file", endpointID) //nolint:staticcheck // reason: using deprecated call until migration to new API
return nil
}
11 changes: 10 additions & 1 deletion network/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ func (nm *networkManager) SaveState(eps []*endpoint) error {
return nm.save()
}

func (nm *networkManager) DeleteState(_ []*EndpointInfo) error {
func (nm *networkManager) DeleteState(epInfos []*EndpointInfo) error {
nm.Lock()
defer nm.Unlock()

Expand All @@ -771,6 +771,15 @@ func (nm *networkManager) DeleteState(_ []*EndpointInfo) error {
// For stateless cni, plugin.ipamInvoker.Delete takes care of removing the state in the main Delete function

if nm.IsStatelessCNIMode() {
for _, epInfo := range epInfos {
if epInfo.NICType == cns.NodeNetworkInterfaceFrontendNIC {
response, err := nm.CnsClient.DeleteEndpointState(context.TODO(), epInfo.EndpointID)
if err != nil {
return errors.Wrapf(err, "Delete endpoint API returned with error for endpoint %s", epInfo.EndpointID)
}
logger.Info("Delete endpoint API returned", zap.String("endpointID", epInfo.EndpointID), zap.String("returnCode", response.ReturnCode.String()))
}
}
return nil
}

Expand Down
Loading