Adding UpdatingIpsNotInUse and Cached NNC to Debug API
In-memory data API - adding 2 more fields to IPAMPoolMonitor
This commit is contained in:
Родитель
9947dba9c0
Коммит
9aa3781a0a
|
@ -180,8 +180,10 @@ type IPAMPoolMonitor interface {
|
|||
|
||||
//struct to expose state values for IPAMPoolMonitor struct
|
||||
type IpamPoolMonitorStateSnapshot struct {
|
||||
MinimumFreeIps int64
|
||||
MaximumFreeIps int64
|
||||
MinimumFreeIps int64
|
||||
MaximumFreeIps int64
|
||||
UpdatingIpsNotInUseCount int
|
||||
CachedNNC nnc.NodeNetworkConfig
|
||||
}
|
||||
|
||||
// Response describes generic response from CNS.
|
||||
|
|
|
@ -16,11 +16,8 @@ const (
|
|||
getAllocatedArg = "Allocated"
|
||||
getAllArg = "All"
|
||||
getPendingReleaseArg = "PendingRelease"
|
||||
<<<<<<< HEAD
|
||||
getPodCmdArg = "getPodContexts"
|
||||
=======
|
||||
getInMemoryData = "getInMemory"
|
||||
>>>>>>> da5071c ([CNS] Debug API to expose In-Memory Data HTTPRestService)
|
||||
|
||||
releaseArg = "release"
|
||||
|
||||
|
@ -34,11 +31,8 @@ const (
|
|||
var (
|
||||
availableCmds = []string{
|
||||
getCmdArg,
|
||||
<<<<<<< HEAD
|
||||
getPodCmdArg,
|
||||
=======
|
||||
getInMemoryData,
|
||||
>>>>>>> da5071c ([CNS] Debug API to expose In-Memory Data HTTPRestService)
|
||||
}
|
||||
|
||||
getFlags = []string{
|
||||
|
@ -60,13 +54,10 @@ func HandleCNSClientCommands(cmd, arg string) error {
|
|||
switch {
|
||||
case strings.EqualFold(getCmdArg, cmd):
|
||||
return getCmd(cnsClient, arg)
|
||||
<<<<<<< HEAD
|
||||
case strings.EqualFold(getPodCmdArg, cmd):
|
||||
return getPodCmd(cnsClient)
|
||||
=======
|
||||
case strings.EqualFold(getInMemoryData, cmd):
|
||||
return getInMemory(cnsClient)
|
||||
>>>>>>> da5071c ([CNS] Debug API to expose In-Memory Data HTTPRestService)
|
||||
default:
|
||||
return fmt.Errorf("No debug cmd supplied, options are: %v", getCmdArg)
|
||||
}
|
||||
|
@ -115,20 +106,13 @@ func printIPAddresses(addrSlice []cns.IPConfigurationStatus) {
|
|||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
func getPodCmd(client *CNSClient) error {
|
||||
|
||||
resp, err := client.GetPodOrchestratorContext()
|
||||
=======
|
||||
func getInMemory(client *CNSClient) error {
|
||||
|
||||
inmemoryData, err := client.GetHTTPServiceData()
|
||||
>>>>>>> da5071c ([CNS] Debug API to expose In-Memory Data HTTPRestService)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
printPodContext(resp)
|
||||
return nil
|
||||
}
|
||||
|
@ -139,7 +123,15 @@ func printPodContext(podContext map[string]string) {
|
|||
fmt.Println(i, " ", orchContext, " : ", podID)
|
||||
i++
|
||||
}
|
||||
=======
|
||||
}
|
||||
|
||||
func getInMemory(client *CNSClient) error {
|
||||
|
||||
inmemoryData, err := client.GetHTTPServiceData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printInMemoryStruct(inmemoryData.HttpRestServiceData)
|
||||
return nil
|
||||
}
|
||||
|
@ -148,5 +140,4 @@ func printInMemoryStruct(data restserver.HttpRestServiceData) {
|
|||
fmt.Println("PodIPIDByOrchestratorContext: ", data.PodIPIDByOrchestratorContext)
|
||||
fmt.Println("PodIPConfigState: ", data.PodIPConfigState)
|
||||
fmt.Println("IPAMPoolMonitor: ", data.IPAMPoolMonitor)
|
||||
>>>>>>> da5071c ([CNS] Debug API to expose In-Memory Data HTTPRestService)
|
||||
}
|
||||
|
|
|
@ -410,3 +410,42 @@ func (cnsClient *CNSClient) GetPodOrchestratorContext() (map[string]string, erro
|
|||
|
||||
return resp.PodContext, err
|
||||
}
|
||||
|
||||
//GetHTTPServiceData gets all public in-memory struct details for debugging purpose
|
||||
func (cnsClient *CNSClient) GetHTTPServiceData() (restserver.GetHTTPServiceDataResponse, error) {
|
||||
var (
|
||||
resp restserver.GetHTTPServiceDataResponse
|
||||
err error
|
||||
res *http.Response
|
||||
)
|
||||
|
||||
url := cnsClient.connectionURL + cns.GetHTTPRestData
|
||||
log.Printf("GetHTTPServiceStruct url %v", url)
|
||||
|
||||
res, err = http.Get(url)
|
||||
if err != nil {
|
||||
log.Errorf("[Azure CNSClient] HTTP Get returned error %v", err.Error())
|
||||
return resp, err
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
errMsg := fmt.Sprintf("[Azure CNSClient] GetHTTPServiceStruct invalid http status code: %v", res.StatusCode)
|
||||
log.Errorf(errMsg)
|
||||
return resp, fmt.Errorf(errMsg)
|
||||
}
|
||||
|
||||
err = json.NewDecoder(res.Body).Decode(&resp)
|
||||
if err != nil {
|
||||
log.Errorf("[Azure CNSClient] Error received while parsing GetHTTPServiceStruct response resp:%v err:%v", res.Body, err.Error())
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if resp.Response.ReturnCode != 0 {
|
||||
log.Errorf("[Azure CNSClient] GetTTPServiceStruct received error response :%v", resp.Response.Message)
|
||||
return resp, fmt.Errorf(resp.Response.Message)
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
nnc "github.com/Azure/azure-container-networking/nodenetworkconfig/api/v1alpha"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/Azure/azure-container-networking/cns"
|
||||
"github.com/Azure/azure-container-networking/cns/common"
|
||||
"github.com/Azure/azure-container-networking/cns/fakes"
|
||||
|
@ -129,7 +132,38 @@ func TestMain(m *testing.M) {
|
|||
httpRestService, err := restserver.NewHTTPRestService(&config, fakes.NewFakeImdsClient(), fakes.NewFakeNMAgentClient())
|
||||
svc = httpRestService.(*restserver.HTTPRestService)
|
||||
svc.Name = "cns-test-server"
|
||||
svc.IPAMPoolMonitor = &fakes.IPAMPoolMonitorFake{FakeMinimumIps: 10, FakeMaximumIps: 20}
|
||||
fakeNNC := nnc.NodeNetworkConfig{
|
||||
TypeMeta: metav1.TypeMeta{},
|
||||
ObjectMeta: metav1.ObjectMeta{},
|
||||
Spec: nnc.NodeNetworkConfigSpec{
|
||||
RequestedIPCount: 16,
|
||||
IPsNotInUse: []string{"abc"},
|
||||
},
|
||||
Status: nnc.NodeNetworkConfigStatus{
|
||||
Scaler: nnc.Scaler{
|
||||
BatchSize: 10,
|
||||
ReleaseThresholdPercent: 50,
|
||||
RequestThresholdPercent: 40,
|
||||
},
|
||||
NetworkContainers: []nnc.NetworkContainer{
|
||||
{
|
||||
ID: "nc1",
|
||||
PrimaryIP: "10.0.0.11",
|
||||
SubnetName: "sub1",
|
||||
IPAssignments: []nnc.IPAssignment{
|
||||
{
|
||||
Name: "ip1",
|
||||
IP: "10.0.0.10",
|
||||
},
|
||||
},
|
||||
DefaultGateway: "10.0.0.1",
|
||||
SubnetAddressSpace: "10.0.0.0/24",
|
||||
Version: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
svc.IPAMPoolMonitor = &fakes.IPAMPoolMonitorFake{FakeMinimumIps: 10, FakeMaximumIps: 20, FakeIpsNotInUseCount: 13, FakecachedNNC: fakeNNC}
|
||||
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to create CNS object, err:%v.\n", err)
|
||||
|
@ -254,8 +288,7 @@ func TestCNSClientPodContextApi(t *testing.T) {
|
|||
podNamespace := "testpodnamespace"
|
||||
desiredIpAddress := "10.0.0.5"
|
||||
|
||||
secondaryIps := make([]string, 0)
|
||||
secondaryIps = append(secondaryIps, desiredIpAddress)
|
||||
secondaryIps := []string{desiredIpAddress}
|
||||
cnsClient, _ := InitCnsClient("")
|
||||
|
||||
addTestStateToRestServer(t, secondaryIps)
|
||||
|
@ -282,4 +315,79 @@ func TestCNSClientPodContextApi(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Log(podcontext)
|
||||
|
||||
// release requested IP address, expect success
|
||||
err = cnsClient.ReleaseIPAddress(orchestratorContext)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to not fail when releasing IP reservation found with context: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCNSClientDebugAPI(t *testing.T) {
|
||||
podName := "testpodname"
|
||||
podNamespace := "testpodnamespace"
|
||||
desiredIpAddress := "10.0.0.5"
|
||||
|
||||
secondaryIps := []string{desiredIpAddress}
|
||||
cnsClient, _ := InitCnsClient("")
|
||||
|
||||
addTestStateToRestServer(t, secondaryIps)
|
||||
|
||||
podInfo := cns.KubernetesPodInfo{PodName: podName, PodNamespace: podNamespace}
|
||||
orchestratorContext, err := json.Marshal(podInfo)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// request IP address
|
||||
_, err1 := cnsClient.RequestIPAddress(orchestratorContext)
|
||||
if err1 != nil {
|
||||
t.Fatalf("get IP from CNS failed with %+v", err1)
|
||||
}
|
||||
|
||||
//test for debug api/cmd to get inmemory data from HTTPRestService
|
||||
inmemory, err := cnsClient.GetHTTPServiceData()
|
||||
if err != nil {
|
||||
t.Errorf("Get in-memory http REST Struct failed %+v", err)
|
||||
}
|
||||
|
||||
if len(inmemory.HttpRestServiceData.PodIPIDByOrchestratorContext) < 1 {
|
||||
t.Errorf("OrchestratorContext map is expected but not returned")
|
||||
}
|
||||
|
||||
//testing Pod IP Configuration Status values set for test
|
||||
podConfig := inmemory.HttpRestServiceData.PodIPConfigState
|
||||
for _, v := range podConfig {
|
||||
if v.IPAddress != "10.0.0.5" || v.State != "Allocated" || v.NCID != "testNcId1" {
|
||||
t.Errorf("Not the expected set values for testing IPConfigurationStatus, %+v", podConfig)
|
||||
}
|
||||
}
|
||||
if len(inmemory.HttpRestServiceData.PodIPConfigState) < 1 {
|
||||
t.Errorf("PodIpConfigState with atleast 1 entry expected but not returned.")
|
||||
}
|
||||
|
||||
testIpamPoolMonitor := inmemory.HttpRestServiceData.IPAMPoolMonitor
|
||||
if testIpamPoolMonitor.MinimumFreeIps != 10 || testIpamPoolMonitor.MaximumFreeIps != 20 || testIpamPoolMonitor.UpdatingIpsNotInUseCount != 13 {
|
||||
t.Errorf("IPAMPoolMonitor state is not reflecting the initial set values, %+v", testIpamPoolMonitor)
|
||||
}
|
||||
|
||||
//check for cached NNC Spec struct values
|
||||
if testIpamPoolMonitor.CachedNNC.Spec.RequestedIPCount != 16 || len(testIpamPoolMonitor.CachedNNC.Spec.IPsNotInUse) != 1 {
|
||||
t.Errorf("IPAMPoolMonitor cached NNC Spec is not reflecting the initial set values, %+v", testIpamPoolMonitor.CachedNNC.Spec)
|
||||
}
|
||||
|
||||
//check for cached NNC Status struct values
|
||||
if testIpamPoolMonitor.CachedNNC.Status.Scaler.BatchSize != 10 || testIpamPoolMonitor.CachedNNC.Status.Scaler.ReleaseThresholdPercent != 50 || testIpamPoolMonitor.CachedNNC.Status.Scaler.RequestThresholdPercent != 40 {
|
||||
t.Errorf("IPAMPoolMonitor cached NNC Status is not reflecting the initial set values, %+v", testIpamPoolMonitor.CachedNNC.Status.Scaler)
|
||||
}
|
||||
|
||||
if len(testIpamPoolMonitor.CachedNNC.Status.NetworkContainers) != 1 {
|
||||
t.Errorf("Expected only one Network Container in the list, %+v", testIpamPoolMonitor.CachedNNC.Status.NetworkContainers)
|
||||
}
|
||||
|
||||
t.Logf("In-memory Data: ")
|
||||
t.Logf("PodIPIDByOrchestratorContext: %+v", inmemory.HttpRestServiceData.PodIPIDByOrchestratorContext)
|
||||
t.Logf("PodIPConfigState: %+v", inmemory.HttpRestServiceData.PodIPConfigState)
|
||||
t.Logf("IPAMPoolMonitor: %+v", inmemory.HttpRestServiceData.IPAMPoolMonitor)
|
||||
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@ import (
|
|||
)
|
||||
|
||||
type IPAMPoolMonitorFake struct {
|
||||
FakeMinimumIps int
|
||||
FakeMaximumIps int
|
||||
FakeMinimumIps int
|
||||
FakeMaximumIps int
|
||||
FakeIpsNotInUseCount int
|
||||
FakecachedNNC nnc.NodeNetworkConfig
|
||||
}
|
||||
|
||||
func NewIPAMPoolMonitorFake() *IPAMPoolMonitorFake {
|
||||
|
@ -31,7 +33,9 @@ func (ipm *IPAMPoolMonitorFake) Reconcile() error {
|
|||
|
||||
func (ipm *IPAMPoolMonitorFake) GetStateSnapshot() cns.IpamPoolMonitorStateSnapshot {
|
||||
return cns.IpamPoolMonitorStateSnapshot{
|
||||
MinimumFreeIps: int64(ipm.FakeMinimumIps),
|
||||
MaximumFreeIps: int64(ipm.FakeMaximumIps),
|
||||
MinimumFreeIps: int64(ipm.FakeMinimumIps),
|
||||
MaximumFreeIps: int64(ipm.FakeMaximumIps),
|
||||
UpdatingIpsNotInUseCount: ipm.FakeIpsNotInUseCount,
|
||||
CachedNNC: ipm.FakecachedNNC,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import (
|
|||
type CNSIPAMPoolMonitor struct {
|
||||
pendingRelease bool
|
||||
|
||||
cachedNNC nnc.NodeNetworkConfig
|
||||
cachedNNC nnc.NodeNetworkConfig
|
||||
updatingIpsNotInUseCount int
|
||||
scalarUnits nnc.Scaler
|
||||
scalarUnits nnc.Scaler
|
||||
|
||||
httpService cns.HTTPService
|
||||
rc requestcontroller.RequestController
|
||||
|
@ -30,9 +30,9 @@ type CNSIPAMPoolMonitor struct {
|
|||
func NewCNSIPAMPoolMonitor(httpService cns.HTTPService, rc requestcontroller.RequestController) *CNSIPAMPoolMonitor {
|
||||
logger.Printf("NewCNSIPAMPoolMonitor: Create IPAM Pool Monitor")
|
||||
return &CNSIPAMPoolMonitor{
|
||||
pendingRelease: false,
|
||||
httpService: httpService,
|
||||
rc: rc,
|
||||
pendingRelease: false,
|
||||
httpService: httpService,
|
||||
rc: rc,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,6 @@ func (pm *CNSIPAMPoolMonitor) cleanPendingRelease() error {
|
|||
|
||||
logger.Printf("[ipam-pool-monitor] cleanPendingRelease: UpdateCRDSpec succeeded for spec %+v", tempNNCSpec)
|
||||
|
||||
|
||||
// save the updated state to cachedSpec
|
||||
pm.cachedNNC.Spec = tempNNCSpec
|
||||
pm.pendingRelease = false
|
||||
|
@ -250,12 +249,14 @@ func (pm *CNSIPAMPoolMonitor) Update(scalar nnc.Scaler, spec nnc.NodeNetworkConf
|
|||
}
|
||||
|
||||
//this function sets the values for state in IPAMPoolMonitor Struct
|
||||
func (pm *CNSIPAMPoolMonitor) GetStateSnapshot() cns.IpamPoolMonitorStateSnapshot{
|
||||
defer pm.mu.Unlock()
|
||||
func (pm *CNSIPAMPoolMonitor) GetStateSnapshot() cns.IpamPoolMonitorStateSnapshot {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
return cns.IpamPoolMonitorStateSnapshot {
|
||||
MinimumFreeIps: pm.MinimumFreeIps,
|
||||
MaximumFreeIps: pm.MaximumFreeIps,
|
||||
return cns.IpamPoolMonitorStateSnapshot{
|
||||
MinimumFreeIps: pm.MinimumFreeIps,
|
||||
MaximumFreeIps: pm.MaximumFreeIps,
|
||||
UpdatingIpsNotInUseCount: pm.updatingIpsNotInUseCount,
|
||||
CachedNNC: pm.cachedNNC,
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче