Skip to content

Commit edb2833

Browse files
authored
Add PendingRelease to CNS on start (#672)
* add pending release on start
1 parent 00f5a84 commit edb2833

File tree

4 files changed

+70
-4
lines changed

4 files changed

+70
-4
lines changed

cns/restserver/internalapi.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ func (service *HTTPRestService) ReconcileNCState(ncRequest *cns.CreateNetworkCon
191191
}
192192
}
193193

194+
err := service.MarkExistingIPsAsPending(spec.IPsNotInUse)
195+
if err != nil {
196+
logger.Errorf("[Azure CNS] Error. Failed to mark IP's as pending %v", spec.IPsNotInUse)
197+
return UnexpectedError
198+
}
199+
194200
return 0
195201
}
196202

@@ -252,5 +258,4 @@ func (service *HTTPRestService) CreateOrUpdateNetworkContainerInternal(req cns.C
252258
}
253259

254260
return returnCode
255-
256261
}

cns/restserver/ipam.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,26 @@ func (service *HTTPRestService) releaseIPConfig(podInfo cns.KubernetesPodInfo) e
194194
return nil
195195
}
196196

197+
// called when CNS is starting up and there are existing ipconfigs in the CRD that are marked as pending
198+
func (service *HTTPRestService) MarkExistingIPsAsPending(pendingIPIDs []string) error {
199+
service.Lock()
200+
defer service.Unlock()
201+
202+
for _, id := range pendingIPIDs {
203+
if ipconfig, exists := service.PodIPConfigState[id]; exists {
204+
if ipconfig.State == cns.Allocated {
205+
return fmt.Errorf("Failed to mark IP [%v] as pending, currently allocated", id)
206+
}
207+
208+
ipconfig.State = cns.PendingRelease
209+
service.PodIPConfigState[id] = ipconfig
210+
} else {
211+
logger.Errorf("Inconsistent state, ipconfig with ID [%v] marked as pending release, but does not exist in state", id)
212+
}
213+
}
214+
return nil
215+
}
216+
197217
func (service *HTTPRestService) GetExistingIPConfig(podInfo cns.KubernetesPodInfo) (cns.PodIpInfo, bool, error) {
198218
var (
199219
podIpInfo cns.PodIpInfo

cns/restserver/ipam_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ func validateIpState(t *testing.T, actualIps []cns.IPConfigurationStatus, expect
534534
}
535535
}
536536

537-
func TestIPAMMarkIPConfigAsPending(t *testing.T) {
537+
func TestIPAMMarkIPCountAsPending(t *testing.T) {
538538
svc := getTestService()
539539
// set state as already allocated
540540
state1, _ := NewPodStateWithOrchestratorContext(testIP1, 24, testPod1GUID, testNCID, cns.Available, testPod1Info)
@@ -574,3 +574,45 @@ func TestIPAMMarkIPConfigAsPending(t *testing.T) {
574574
t.Fatalf("Unexpected failure releasing IP: %+v", err)
575575
}
576576
}
577+
578+
func TestIPAMMarkExistingIPConfigAsPending(t *testing.T) {
579+
svc := getTestService()
580+
581+
// Add already allocated pod ip to state
582+
svc.PodIPIDByOrchestratorContext[testPod1Info.GetOrchestratorContextKey()] = testPod1GUID
583+
state1, _ := NewPodStateWithOrchestratorContext(testIP1, 24, testPod1GUID, testNCID, cns.Allocated, testPod1Info)
584+
state2 := NewPodState(testIP2, 24, testPod2GUID, testNCID, cns.Available)
585+
586+
ipconfigs := map[string]cns.IPConfigurationStatus{
587+
state1.ID: state1,
588+
state2.ID: state2,
589+
}
590+
err := UpdatePodIpConfigState(t, svc, ipconfigs)
591+
if err != nil {
592+
t.Fatalf("Expected to not fail adding IP's to state: %+v", err)
593+
}
594+
595+
// mark available ip as as pending
596+
pendingIPIDs := []string{testPod2GUID}
597+
err = svc.MarkExistingIPsAsPending(pendingIPIDs)
598+
if err != nil {
599+
t.Fatalf("Expected to successfully mark available ip as pending")
600+
}
601+
602+
pendingIPConfigs := svc.GetPendingReleaseIPConfigs()
603+
if pendingIPConfigs[0].ID != testPod2GUID {
604+
t.Fatalf("Expected to see ID %v in pending release ipconfigs, actual %+v", testPod2GUID, pendingIPConfigs)
605+
}
606+
607+
// attempt to mark allocated ipconfig as pending, expect fail
608+
pendingIPIDs = []string{testPod1GUID}
609+
err = svc.MarkExistingIPsAsPending(pendingIPIDs)
610+
if err == nil {
611+
t.Fatalf("Expected to fail when marking allocated ip as pending")
612+
}
613+
614+
allocatedIPConfigs := svc.GetAllocatedIPConfigs()
615+
if allocatedIPConfigs[0].ID != testPod1GUID {
616+
t.Fatalf("Expected to see ID %v in pending release ipconfigs, actual %+v", testPod1GUID, allocatedIPConfigs)
617+
}
618+
}

cns/service/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,7 @@ func main() {
477477
}
478478
}()
479479

480-
ctx, cancel := context.WithCancel(context.Background())
481-
defer cancel()
480+
ctx := context.Background()
482481
go func() {
483482
if err := httpRestServiceImplementation.IPAMPoolMonitor.Start(ctx, poolIPAMRefreshRateInMilliseconds); err != nil {
484483
logger.Errorf("[Azure CNS] Failed to start pool monitor with err: %v", err)

0 commit comments

Comments
 (0)