Skip to content
Merged
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
18 changes: 15 additions & 3 deletions cns/NetworkContainerContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,25 @@ type GetNetworkContainerResponse struct {
}

type GetIPConfigRequest struct {
DesiredIPConfig IPSubnet
DesiredIPAddress string
OrchestratorContext json.RawMessage
}

type GetIPConfigResponse struct {
IPConfiguration IPConfiguration
Response Response
PodIpInfo PodIpInfo
Response Response
}

// DeleteNetworkContainerRequest specifies the details about the request to delete a specifc network container.
type PodIpInfo struct {
PodIPConfig IPSubnet
NetworkContainerPrimaryIPConfig IPConfiguration
HostPrimaryIPInfo HostIPInfo
}

// DeleteNetworkContainerRequest specifies the details about the request to delete a specifc network container.
type HostIPInfo struct {
IPConfig IPSubnet
}

// DeleteNetworkContainerRequest specifies the details about the request to delete a specifc network container.
Expand Down
28 changes: 19 additions & 9 deletions cns/cnsclient/cnsclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
const (
primaryIp = "10.0.0.5"
gatewayIp = "10.0.0.1"
subnetPrfixLength = 24
dockerContainerType = cns.Docker
)

Expand All @@ -40,7 +41,7 @@ func addTestStateToRestServer(t *testing.T, secondaryIps []string) {
ipConfig.GatewayIPAddress = gatewayIp
var ipSubnet cns.IPSubnet
ipSubnet.IPAddress = primaryIp
ipSubnet.PrefixLength = 32
ipSubnet.PrefixLength = subnetPrfixLength
ipConfig.IPSubnet = ipSubnet
secondaryIPConfigs := make(map[string]cns.SecondaryIPConfig)

Expand Down Expand Up @@ -72,8 +73,8 @@ func getIPNetFromResponse(resp *cns.GetIPConfigResponse) (net.IPNet, error) {
)

// set result ipconfig from CNS Response Body
prefix := strconv.Itoa(int(resp.IPConfiguration.IPSubnet.PrefixLength))
ip, ipnet, err := net.ParseCIDR(resp.IPConfiguration.IPSubnet.IPAddress + "/" + prefix)
prefix := strconv.Itoa(int(resp.PodIpInfo.PodIPConfig.PrefixLength))
ip, ipnet, err := net.ParseCIDR(resp.PodIpInfo.PodIPConfig.IPAddress + "/" + prefix)
if err != nil {
return resultIPnet, err
}
Expand Down Expand Up @@ -155,7 +156,7 @@ func TestCNSClientRequestAndRelease(t *testing.T) {
podNamespace := "testpodnamespace"
desiredIpAddress := "10.0.0.5"
ip := net.ParseIP(desiredIpAddress)
_, ipnet, _ := net.ParseCIDR("10.0.0.5/32")
_, ipnet, _ := net.ParseCIDR("10.0.0.5/24")
desired := net.IPNet{
IP: ip,
Mask: ipnet.Mask,
Expand Down Expand Up @@ -185,13 +186,22 @@ func TestCNSClientRequestAndRelease(t *testing.T) {
t.Fatalf("get IP from CNS failed with %+v", err)
}

// validate gateway and dnsservers
if reflect.DeepEqual(resp.IPConfiguration.DNSServers, dnsservers) != true {
t.Fatalf("DnsServer is not added as expected ipConfig %+v, expected dnsServers: %+v", resp.IPConfiguration, dnsservers)
podIPInfo := resp.PodIpInfo
if reflect.DeepEqual(podIPInfo.NetworkContainerPrimaryIPConfig.IPSubnet.IPAddress, primaryIp) != true {
t.Fatalf("PrimarIP is not added as expected ipConfig %+v, expected primaryIP: %+v", podIPInfo.NetworkContainerPrimaryIPConfig, primaryIp)
}

if reflect.DeepEqual(resp.IPConfiguration.GatewayIPAddress, gatewayIp) != true {
t.Fatalf("Gateway is not added as expected ipConfig %+v, expected GatewayIp: %+v", resp.IPConfiguration, gatewayIp)
if podIPInfo.NetworkContainerPrimaryIPConfig.IPSubnet.PrefixLength != subnetPrfixLength {
t.Fatalf("Primary IP Prefix length is not added as expected ipConfig %+v, expected: %+v", podIPInfo.NetworkContainerPrimaryIPConfig, subnetPrfixLength)
}

// validate DnsServer and Gateway Ip as the same configured for Primary IP
if reflect.DeepEqual(podIPInfo.NetworkContainerPrimaryIPConfig.DNSServers, dnsservers) != true {
t.Fatalf("DnsServer is not added as expected ipConfig %+v, expected dnsServers: %+v", podIPInfo.NetworkContainerPrimaryIPConfig, dnsservers)
}

if reflect.DeepEqual(podIPInfo.NetworkContainerPrimaryIPConfig.GatewayIPAddress, gatewayIp) != true {
t.Fatalf("Gateway is not added as expected ipConfig %+v, expected GatewayIp: %+v", podIPInfo.NetworkContainerPrimaryIPConfig, gatewayIp)
}

resultIPnet, err := getIPNetFromResponse(resp)
Expand Down
7 changes: 1 addition & 6 deletions cns/restserver/internalapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,14 @@ func (service *HTTPRestService) ReconcileNCState(ncRequest *cns.CreateNetworkCon
if podInfo, exists := podInfoByIp[secIpConfig.IPAddress]; exists {
log.Logf("SecondaryIP %+v is allocated to Pod. %+v, ncId: %s", secIpConfig, podInfo, ncRequest.NetworkContainerid)

desiredIPConfig := cns.IPSubnet{
IPAddress: secIpConfig.IPAddress,
PrefixLength: 32, //todo: remove PrefixLenght in
}

kubernetesPodInfo := cns.KubernetesPodInfo{
PodName: podInfo.PodName,
PodNamespace: podInfo.PodNamespace,
}
jsonContext, _ := json.Marshal(kubernetesPodInfo)

ipconfigRequest := cns.GetIPConfigRequest{
DesiredIPConfig: desiredIPConfig,
DesiredIPAddress: secIpConfig.IPAddress,
OrchestratorContext: jsonContext,
}

Expand Down
3 changes: 2 additions & 1 deletion cns/restserver/internalapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
const (
primaryIp = "10.0.0.5"
gatewayIp = "10.0.0.1"
subnetPrfixLength = 24
dockerContainerType = cns.Docker
)

Expand Down Expand Up @@ -256,7 +257,7 @@ func generateNetworkContainerRequest(secondaryIps map[string]cns.SecondaryIPConf
ipConfig.GatewayIPAddress = gatewayIp
var ipSubnet cns.IPSubnet
ipSubnet.IPAddress = primaryIp
ipSubnet.PrefixLength = 32
ipSubnet.PrefixLength = subnetPrfixLength
ipConfig.IPSubnet = ipSubnet

req := cns.CreateNetworkContainerRequest{
Expand Down
62 changes: 31 additions & 31 deletions cns/restserver/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (service *HTTPRestService) requestIPConfigHandler(w http.ResponseWriter, r
var (
err error
ipconfigRequest cns.GetIPConfigRequest
ipconfiguration cns.IPConfiguration
podIpInfo cns.PodIpInfo
returnCode int
returnMessage string
)
Expand All @@ -32,7 +32,7 @@ func (service *HTTPRestService) requestIPConfigHandler(w http.ResponseWriter, r
// retrieve ipconfig from nc
_, returnCode, returnMessage = service.validateIpConfigRequest(ipconfigRequest)
if returnCode == Success {
if ipconfiguration, err = requestIPConfigHelper(service, ipconfigRequest); err != nil {
if podIpInfo, err = requestIPConfigHelper(service, ipconfigRequest); err != nil {
returnCode = FailedToAllocateIpConfig
returnMessage = fmt.Sprintf("AllocateIPConfig failed: %v", err)
}
Expand All @@ -46,7 +46,7 @@ func (service *HTTPRestService) requestIPConfigHandler(w http.ResponseWriter, r
reserveResp := &cns.GetIPConfigResponse{
Response: resp,
}
reserveResp.IPConfiguration = ipconfiguration
reserveResp.PodIpInfo = podIpInfo

err = service.Listener.Encode(w, &reserveResp)
logger.Response(service.Name, reserveResp, resp.ReturnCode, ReturnCodeToString(resp.ReturnCode), err)
Expand Down Expand Up @@ -158,10 +158,10 @@ func (service *HTTPRestService) releaseIPConfig(podInfo cns.KubernetesPodInfo) e
return nil
}

func (service *HTTPRestService) GetExistingIPConfig(podInfo cns.KubernetesPodInfo) (cns.IPConfiguration, bool, error) {
func (service *HTTPRestService) GetExistingIPConfig(podInfo cns.KubernetesPodInfo) (cns.PodIpInfo, bool, error) {
var (
ipConfiguration cns.IPConfiguration
isExist bool
podIpInfo cns.PodIpInfo
isExist bool
)

service.RLock()
Expand All @@ -170,19 +170,19 @@ func (service *HTTPRestService) GetExistingIPConfig(podInfo cns.KubernetesPodInf
ipID := service.PodIPIDByOrchestratorContext[podInfo.GetOrchestratorContextKey()]
if ipID != "" {
if ipState, isExist := service.PodIPConfigState[ipID]; isExist {
err := service.populateIpConfigInfoUntransacted(ipState, &ipConfiguration)
return ipConfiguration, isExist, err
err := service.populateIpConfigInfoUntransacted(ipState, &podIpInfo)
return podIpInfo, isExist, err
}

logger.Errorf("Failed to get existing ipconfig. Pod to IPID exists, but IPID to IPConfig doesn't exist, CNS State potentially corrupt")
return ipConfiguration, isExist, fmt.Errorf("Failed to get existing ipconfig. Pod to IPID exists, but IPID to IPConfig doesn't exist, CNS State potentially corrupt")
return podIpInfo, isExist, fmt.Errorf("Failed to get existing ipconfig. Pod to IPID exists, but IPID to IPConfig doesn't exist, CNS State potentially corrupt")
}

return ipConfiguration, isExist, nil
return podIpInfo, isExist, nil
}

func (service *HTTPRestService) AllocateDesiredIPConfig(podInfo cns.KubernetesPodInfo, desiredIPAddress string, orchestratorContext json.RawMessage) (cns.IPConfiguration, error) {
var ipConfiguration cns.IPConfiguration
func (service *HTTPRestService) AllocateDesiredIPConfig(podInfo cns.KubernetesPodInfo, desiredIPAddress string, orchestratorContext json.RawMessage) (cns.PodIpInfo, error) {
var podIpInfo cns.PodIpInfo
service.Lock()
defer service.Unlock()

Expand All @@ -197,62 +197,62 @@ func (service *HTTPRestService) AllocateDesiredIPConfig(podInfo cns.KubernetesPo
} else {
var pInfo cns.KubernetesPodInfo
json.Unmarshal(ipState.OrchestratorContext, &pInfo)
return ipConfiguration, fmt.Errorf("Desired IP is already allocated %+v to Pod: %+v, requested for pod %+v", ipState, pInfo, podInfo)
return podIpInfo, fmt.Errorf("Desired IP is already allocated %+v to Pod: %+v, requested for pod %+v", ipState, pInfo, podInfo)
}
} else if ipState.State == cns.Available {
service.setIPConfigAsAllocated(ipState, podInfo, orchestratorContext)
found = true
} else {
return ipConfiguration, fmt.Errorf("Desired IP is not available %+v", ipState)
return podIpInfo, fmt.Errorf("Desired IP is not available %+v", ipState)
}

if found {
err := service.populateIpConfigInfoUntransacted(ipState, &ipConfiguration)
return ipConfiguration, err
err := service.populateIpConfigInfoUntransacted(ipState, &podIpInfo)
return podIpInfo, err
}
}
}
return ipConfiguration, fmt.Errorf("Requested IP not found in pool")
return podIpInfo, fmt.Errorf("Requested IP not found in pool")
}

func (service *HTTPRestService) AllocateAnyAvailableIPConfig(podInfo cns.KubernetesPodInfo, orchestratorContext json.RawMessage) (cns.IPConfiguration, error) {
var ipConfiguration cns.IPConfiguration
func (service *HTTPRestService) AllocateAnyAvailableIPConfig(podInfo cns.KubernetesPodInfo, orchestratorContext json.RawMessage) (cns.PodIpInfo, error) {
var podIpInfo cns.PodIpInfo

service.Lock()
defer service.Unlock()

for _, ipState := range service.PodIPConfigState {
if ipState.State == cns.Available {
err := service.populateIpConfigInfoUntransacted(ipState, &ipConfiguration)
err := service.populateIpConfigInfoUntransacted(ipState, &podIpInfo)
if err == nil {
service.setIPConfigAsAllocated(ipState, podInfo, orchestratorContext)
}
return ipConfiguration, err
return podIpInfo, err
}
}

return ipConfiguration, fmt.Errorf("No more free IP's available, trigger batch")
return podIpInfo, fmt.Errorf("No more free IP's available, trigger batch")
}

// If IPConfig is already allocated for pod, it returns that else it returns one of the available ipconfigs.
func requestIPConfigHelper(service *HTTPRestService, req cns.GetIPConfigRequest) (cns.IPConfiguration, error) {
func requestIPConfigHelper(service *HTTPRestService, req cns.GetIPConfigRequest) (cns.PodIpInfo, error) {
var (
podInfo cns.KubernetesPodInfo
ipConfiguration cns.IPConfiguration
isExist bool
err error
podInfo cns.KubernetesPodInfo
podIpInfo cns.PodIpInfo
isExist bool
err error
)

// check if ipconfig already allocated for this pod and return if exists or error
// if error, ipstate is nil, if exists, ipstate is not nil and error is nil
json.Unmarshal(req.OrchestratorContext, &podInfo)
if ipConfiguration, isExist, err = service.GetExistingIPConfig(podInfo); err != nil || isExist {
return ipConfiguration, err
if podIpInfo, isExist, err = service.GetExistingIPConfig(podInfo); err != nil || isExist {
return podIpInfo, err
}

// return desired IPConfig
if req.DesiredIPConfig.IPAddress != "" {
return service.AllocateDesiredIPConfig(podInfo, req.DesiredIPConfig.IPAddress, req.OrchestratorContext)
if req.DesiredIPAddress != "" {
return service.AllocateDesiredIPConfig(podInfo, req.DesiredIPAddress, req.OrchestratorContext)
}

// return any free IPConfig
Expand Down
Loading