CNS Debug API to expose PodIpIdByOrchrestratorContext

This API exposes the Httpservice struct field to display
map of OrchestratorContext->PodIpID (UUID) and includes
debug command getPodContexts for CLI use-case.
This commit is contained in:
Kshitija Murudi 2021-03-17 10:01:59 -07:00
Родитель 455f5cb9f0
Коммит dbb4e129b8
6 изменённых файлов: 135 добавлений и 10 удалений

Просмотреть файл

@ -23,6 +23,7 @@ const (
RequestIPConfig = "/network/requestipconfig"
ReleaseIPConfig = "/network/releaseipconfig"
GetIPAddresses = "/debug/getipaddresses"
GetPodIPOrchestratorContext = "/debug/getpodcontext"
)
// NetworkContainer Prefixes
@ -248,6 +249,12 @@ type GetIPAddressStatusResponse struct {
Response Response
}
//GetPodContextResponse is used in CNS Client debug mode to get mapping of Orchestrator Context to Pod IP UUID
type GetPodContextResponse struct {
PodContext map[string]string
Response Response
}
// IPAddressState Only used in the GetIPConfig API to return IP's that match a filter
type IPAddressState struct {
IPAddress string

Просмотреть файл

@ -15,6 +15,7 @@ const (
getAllocatedArg = "Allocated"
getAllArg = "All"
getPendingReleaseArg = "PendingRelease"
getPodCmdArg = "getPodContexts"
releaseArg = "release"
@ -28,6 +29,7 @@ const (
var (
availableCmds = []string{
getCmdArg,
getPodCmdArg,
}
getFlags = []string{
@ -49,6 +51,8 @@ func HandleCNSClientCommands(cmd, arg string) error {
switch {
case strings.EqualFold(getCmdArg, cmd):
return getCmd(cnsClient, arg)
case strings.EqualFold(getPodCmdArg, cmd):
return getPodCmd(cnsClient)
default:
return fmt.Errorf("No debug cmd supplied, options are: %v", getCmdArg)
}
@ -96,3 +100,22 @@ func printIPAddresses(addrSlice []cns.IPConfigurationStatus) {
cns.IPConfigurationStatus.String(addr)
}
}
func getPodCmd(client *CNSClient) error {
resp, err := client.GetPodOrchestratorContext()
if err != nil {
return err
}
printPodContext(resp)
return nil
}
func printPodContext(podContext map[string]string){
var i = 1
for orchContext,podID := range podContext {
fmt.Println(i, " ", orchContext, " : ", podID)
i++
}
}

Просмотреть файл

@ -371,3 +371,50 @@ func (cnsClient *CNSClient) GetIPAddressesMatchingStates(StateFilter ...string)
return resp.IPConfigurationStatus, err
}
//GetPodOrchestratorContext calls GetPodIpOrchestratorContext API on CNS
func (cnsClient *CNSClient) GetPodOrchestratorContext() (map[string]string, error) {
var (
resp cns.GetPodContextResponse
err error
res *http.Response
body bytes.Buffer
)
url := cnsClient.connectionURL + cns.GetPodIPOrchestratorContext
log.Printf("GetPodIPOrchestratorContext url %v", url)
payload := ""
err = json.NewEncoder(&body).Encode(payload)
if err != nil {
log.Errorf("encoding json failed with %v", err)
return resp.PodContext, err
}
res, err = http.Post(url, contentTypeJSON, &body)
if err != nil {
log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error())
return resp.PodContext, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
errMsg := fmt.Sprintf("[Azure CNSClient] GetPodContext invalid http status code: %v", res.StatusCode)
log.Errorf(errMsg)
return resp.PodContext, fmt.Errorf(errMsg)
}
err = json.NewDecoder(res.Body).Decode(&resp)
if err != nil {
log.Errorf("[Azure CNSClient] Error received while parsing GetPodContext response resp:%v err:%v", res.Body, err.Error())
return resp.PodContext, err
}
if resp.Response.ReturnCode != 0 {
log.Errorf("[Azure CNSClient] GetPodContext received error response :%v", resp.Response.Message)
return resp.PodContext, fmt.Errorf(resp.Response.Message)
}
return resp.PodContext, err
}

Просмотреть файл

@ -11,7 +11,6 @@ import (
"reflect"
"strconv"
"testing"
"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/common"
"github.com/Azure/azure-container-networking/cns/fakes"
@ -226,14 +225,8 @@ func TestCNSClientRequestAndRelease(t *testing.T) {
if reflect.DeepEqual(desired, resultIPnet) != true {
t.Fatalf("Desired result not matching actual result, expected: %+v, actual: %+v", desired, resultIPnet)
}
// 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)
}
ipaddresses, err := cnsClient.GetIPAddressesMatchingStates(cns.Available)
//checking for allocated IP address and pod context printing before ReleaseIPAddress is called
ipaddresses, err := cnsClient.GetIPAddressesMatchingStates(cns.Allocated)
if err != nil {
t.Fatalf("Get allocated IP addresses failed %+v", err)
}
@ -242,8 +235,24 @@ func TestCNSClientRequestAndRelease(t *testing.T) {
t.Fatalf("Number of available IP addresses expected to be 1, actual %+v", ipaddresses)
}
if ipaddresses[0].IPAddress != desiredIpAddress && ipaddresses[0].State != cns.Available {
if ipaddresses[0].IPAddress != desiredIpAddress && ipaddresses[0].State != cns.Allocated {
t.Fatalf("Available IP address does not match expected, address state: %+v", ipaddresses)
}
fmt.Println(ipaddresses)
//test for pod ip by orch context map
podcontext, err := cnsClient.GetPodOrchestratorContext()
if err != nil {
t.Fatalf("Get pod ip by orchestrator context failed %+v", err)
}
if len(podcontext) < 1 {
t.Fatalf("Error in getting podcontext %+v", podcontext)
}
fmt.Println(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)
}
}

Просмотреть файл

@ -181,6 +181,44 @@ func (service *HTTPRestService) GetPodIPConfigState() map[string]cns.IPConfigura
return service.PodIPConfigState
}
func (service *HTTPRestService) getPodIPIDByOrchestratorContexthandler(w http.ResponseWriter, r *http.Request) {
var (
req string
resp cns.GetPodContextResponse
statusCode int
returnMessage string
err error
)
statusCode = UnexpectedError
defer func() {
if err != nil {
resp.Response.ReturnCode = statusCode
resp.Response.Message = returnMessage
}
err = service.Listener.Encode(w, &resp)
logger.Response(service.Name, resp, resp.Response.ReturnCode, ReturnCodeToString(resp.Response.ReturnCode), err)
}()
err = service.Listener.Decode(w, r, &req)
if err != nil {
returnMessage = err.Error()
return
}
resp.PodContext = service.GetPodIPIDByOrchestratorContext()
return
}
func (service *HTTPRestService) GetPodIPIDByOrchestratorContext() map[string]string {
service.RLock()
defer service.RUnlock()
return service.PodIPIDByOrchestratorContext
}
// GetPendingProgramIPConfigs returns list of IPs which are in pending program status
func (service *HTTPRestService) GetPendingProgramIPConfigs() []cns.IPConfigurationStatus {
service.RLock()

Просмотреть файл

@ -174,6 +174,7 @@ func (service *HTTPRestService) Init(config *common.ServiceConfig) error {
listener.AddHandler(cns.ReleaseIPConfig, service.releaseIPConfigHandler)
listener.AddHandler(cns.NmAgentSupportedApisPath, service.nmAgentSupportedApisHandler)
listener.AddHandler(cns.GetIPAddresses, service.getIPAddressesHandler)
listener.AddHandler(cns.GetPodIPOrchestratorContext, service.getPodIPIDByOrchestratorContexthandler)
// handlers for v0.2
listener.AddHandler(cns.V2Prefix+cns.SetEnvironmentPath, service.setEnvironment)