Skip to content

Commit ddfbaa5

Browse files
committed
Added DeleteEndpointState handler for removing endpoint state from CNS in stateless cni case
Signed-off-by: Tamilmani <[email protected]>
1 parent 3db8140 commit ddfbaa5

File tree

6 files changed

+125
-4
lines changed

6 files changed

+125
-4
lines changed

cni/network/network.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,10 +1159,10 @@ func (plugin *NetPlugin) Delete(args *cniSkel.CmdArgs) error {
11591159
}
11601160
}
11611161
}
1162-
logger.Info("Deleting the state from the cni statefile")
1162+
logger.Info("Deleting endpoint state from statefile")
11631163
err = plugin.nm.DeleteState(epInfos)
11641164
if err != nil {
1165-
return plugin.RetriableError(fmt.Errorf("failed to save state: %w", err))
1165+
return plugin.RetriableError(fmt.Errorf("failed to delete state: %w", err))
11661166
}
11671167

11681168
return err

cns/client/client.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,3 +1100,35 @@ func (c *Client) UpdateEndpoint(ctx context.Context, endpointID string, ipInfo m
11001100

11011101
return &response, nil
11021102
}
1103+
1104+
func (c *Client) DeleteEndpointState(ctx context.Context, endpointID string) (*cns.Response, error) {
1105+
// build the request
1106+
u := c.routes[cns.EndpointAPI]
1107+
uString := u.String() + endpointID
1108+
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uString, http.NoBody)
1109+
if err != nil {
1110+
return nil, errors.Wrap(err, "failed to build request")
1111+
}
1112+
req.Header.Set(headerContentType, contentTypeJSON)
1113+
res, err := c.client.Do(req)
1114+
if err != nil {
1115+
return nil, &ConnectionFailureErr{cause: err}
1116+
}
1117+
1118+
defer res.Body.Close()
1119+
if res.StatusCode != http.StatusOK {
1120+
return nil, errors.Errorf("http response %d", res.StatusCode)
1121+
}
1122+
1123+
var response cns.Response
1124+
err = json.NewDecoder(res.Body).Decode(&response)
1125+
if err != nil {
1126+
return nil, errors.Wrap(err, "failed to decode CNS Response")
1127+
}
1128+
1129+
if response.ReturnCode != 0 {
1130+
return nil, errors.New(response.Message)
1131+
}
1132+
1133+
return &response, nil
1134+
}

cns/endpointmanager/endpointmanager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type EndpointManager struct {
1414
type releaseIPsClient interface {
1515
ReleaseIPs(ctx context.Context, ipconfig cns.IPConfigsRequest) error
1616
GetEndpoint(ctx context.Context, endpointID string) (*restserver.GetEndpointResponse, error)
17+
DeleteEndpointState(ctx context.Context, endpointID string) (*cns.Response, error)
1718
}
1819

1920
func WithPlatformReleaseIPsManager(cli releaseIPsClient) *EndpointManager {

cns/endpointmanager/endpointmanager_windows.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/Azure/azure-container-networking/cns"
77
"github.com/Azure/azure-container-networking/cns/hnsclient"
88
"github.com/Azure/azure-container-networking/cns/logger"
9+
"github.com/Azure/azure-container-networking/cns/types"
910
"github.com/pkg/errors"
1011
)
1112

@@ -16,7 +17,19 @@ func (em *EndpointManager) ReleaseIPs(ctx context.Context, ipconfigreq cns.IPCon
1617
if err := em.deleteEndpoint(ctx, ipconfigreq.InfraContainerID); err != nil {
1718
logger.Errorf("failed to remove HNS endpoint %s", err.Error())
1819
}
19-
return errors.Wrap(em.cli.ReleaseIPs(ctx, ipconfigreq), "failed to release IP from CNS")
20+
21+
if err := em.cli.ReleaseIPs(ctx, ipconfigreq); err != nil {
22+
return errors.Wrap(err, "failed to release IP from CNS")
23+
}
24+
25+
res, err := em.cli.DeleteEndpointState(ctx, ipconfigreq.InfraContainerID)
26+
if err != nil {
27+
if res.ReturnCode != types.NotFound {
28+
return errors.Wrap(err, "")
29+
}
30+
}
31+
32+
return nil
2033
}
2134

2235
// deleteEndpoint API to get the state and then remove assiciated HNS

cns/restserver/ipam.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,11 +1141,76 @@ func (service *HTTPRestService) EndpointHandlerAPI(w http.ResponseWriter, r *htt
11411141
service.GetEndpointHandler(w, r)
11421142
case http.MethodPatch:
11431143
service.UpdateEndpointHandler(w, r)
1144+
case http.MethodDelete:
1145+
service.DeleteEndpointStateHandler(w, r)
11441146
default:
11451147
logger.Errorf("[EndpointHandlerAPI] EndpointHandler API expect http Get or Patch method")
11461148
}
11471149
}
11481150

1151+
func (service *HTTPRestService) DeleteEndpointStateHandler(w http.ResponseWriter, r *http.Request) {
1152+
opName := "DeleteEndpointStateHandler"
1153+
logger.Printf("[DeleteEndpointStateHandler] DeleteEndpointState for %s", r.URL.Path) //nolint:staticcheck // reason: using deprecated call until migration to new API
1154+
endpointID := strings.TrimPrefix(r.URL.Path, cns.EndpointPath)
1155+
1156+
if service.EndpointStateStore == nil {
1157+
response := cns.Response{
1158+
ReturnCode: types.NilEndpointStateStore,
1159+
Message: "[DeleteEndpointStateHandler] EndpointStateStore is not initialized",
1160+
}
1161+
err := common.Encode(w, &response)
1162+
logger.Response(opName, response, response.ReturnCode, err) //nolint:staticcheck // reason: using deprecated call until migration to new API
1163+
return
1164+
}
1165+
1166+
// Delete the endpoint from state
1167+
err := service.DeleteEndpointStateHelper(endpointID)
1168+
if err != nil {
1169+
response := cns.Response{
1170+
ReturnCode: types.UnexpectedError,
1171+
Message: fmt.Sprintf("[DeleteEndpointStateHandler] Failed to delete endpoint state for %s with error: %s", endpointID, err.Error()),
1172+
}
1173+
1174+
if errors.Is(err, ErrEndpointStateNotFound) {
1175+
response.ReturnCode = types.NotFound
1176+
}
1177+
1178+
err = common.Encode(w, &response)
1179+
logger.Response(opName, response, response.ReturnCode, err) //nolint:staticcheck // reason: using deprecated call until migration to new API
1180+
return
1181+
}
1182+
1183+
response := cns.Response{
1184+
ReturnCode: types.Success,
1185+
Message: "[DeleteEndpointStateHandler] Endpoint state deleted successfully",
1186+
}
1187+
err = common.Encode(w, &response)
1188+
logger.Response(opName, response, response.ReturnCode, err) //nolint:staticcheck // reason: using deprecated call until migration to new API
1189+
}
1190+
1191+
func (service *HTTPRestService) DeleteEndpointStateHelper(endpointID string) error {
1192+
if service.EndpointStateStore == nil {
1193+
return ErrStoreEmpty
1194+
}
1195+
logger.Printf("[deleteEndpointState] Deleting Endpoint state from state file %s", endpointID) //nolint:staticcheck // reason: using deprecated call until migration to new API
1196+
_, endpointExist := service.EndpointState[endpointID]
1197+
if !endpointExist {
1198+
logger.Printf("[deleteEndpointState] endpoint could not be found in the statefile %s", endpointID) //nolint:staticcheck // reason: using deprecated call until migration to new API
1199+
return fmt.Errorf("[deleteEndpointState] endpoint %s: %w", endpointID, ErrEndpointStateNotFound)
1200+
}
1201+
1202+
// Delete the endpoint from the state
1203+
delete(service.EndpointState, endpointID)
1204+
1205+
// Write the updated state back to the store
1206+
err := service.EndpointStateStore.Write(EndpointStoreKey, service.EndpointState)
1207+
if err != nil {
1208+
return fmt.Errorf("[deleteEndpointState] failed to write endpoint state to store: %w", err)
1209+
}
1210+
logger.Printf("[deleteEndpointState] successfully deleted endpoint %s from state file", endpointID) //nolint:staticcheck // reason: using deprecated call until migration to new API
1211+
return nil
1212+
}
1213+
11491214
// GetEndpointHandler handles the incoming GetEndpoint requests with http Get method
11501215
func (service *HTTPRestService) GetEndpointHandler(w http.ResponseWriter, r *http.Request) {
11511216
opName := "getEndpointState"

network/manager.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ func (nm *networkManager) SaveState(eps []*endpoint) error {
762762
return nm.save()
763763
}
764764

765-
func (nm *networkManager) DeleteState(_ []*EndpointInfo) error {
765+
func (nm *networkManager) DeleteState(epInfos []*EndpointInfo) error {
766766
nm.Lock()
767767
defer nm.Unlock()
768768

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

774774
if nm.IsStatelessCNIMode() {
775+
for _, epInfo := range epInfos {
776+
if epInfo.NICType == cns.NodeNetworkInterfaceFrontendNIC || epInfo.NICType == cns.NodeNetworkInterfaceAccelnetFrontendNIC {
777+
response, err := nm.CnsClient.DeleteEndpointState(context.TODO(), epInfo.EndpointID)
778+
if err != nil {
779+
return errors.Wrapf(err, "Delete endpoint API returned with error for endpoint %s", epInfo.EndpointID)
780+
}
781+
logger.Info("Delete endpoint succeeded", zap.String("endpointID", epInfo.EndpointID), zap.String("returnCode", response.ReturnCode.String()))
782+
break
783+
}
784+
}
775785
return nil
776786
}
777787

0 commit comments

Comments
 (0)