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: 3 additions & 15 deletions cns/NetworkContainerContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"net"
"strconv"
"strings"

"github.com/Azure/azure-container-networking/cns/types"
)

// Container Network Service DNC Contract
Expand Down Expand Up @@ -60,20 +62,6 @@ const (
Vxlan = "Vxlan"
)

// IPConfig States for CNS IPAM
type IPConfigState string

const (
// Available IPConfigState for available IPs.
Available IPConfigState = "Available"
// Allocated IPConfigState for allocated IPs.
Allocated IPConfigState = "Allocated"
// PendingRelease IPConfigState for pending release IPs.
PendingRelease IPConfigState = "PendingRelease"
// PendingProgramming IPConfigState for pending programming IPs.
PendingProgramming IPConfigState = "PendingProgramming"
)

// ChannelMode :- CNS channel modes
const (
Direct = "Direct"
Expand Down Expand Up @@ -373,7 +361,7 @@ type IPConfigResponse struct {
// GetIPAddressesRequest is used in CNS IPAM mode to get the states of IPConfigs
// The IPConfigStateFilter is a slice of IPs to fetch from CNS that match those states
type GetIPAddressesRequest struct {
IPConfigStateFilter []IPConfigState
IPConfigStateFilter []types.IPState
}

// GetIPAddressStateResponse is used in CNS IPAM mode as a response to get IP address state
Expand Down
10 changes: 5 additions & 5 deletions cns/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type HTTPService interface {
SyncNodeStatus(string, string, string, json.RawMessage) (types.ResponseCode, string)
GetPendingProgramIPConfigs() []IPConfigurationStatus
GetAvailableIPConfigs() []IPConfigurationStatus
GetAllocatedIPConfigs() []IPConfigurationStatus
GetAssignedIPConfigs() []IPConfigurationStatus
GetPendingReleaseIPConfigs() []IPConfigurationStatus
GetPodIPConfigState() map[string]IPConfigurationStatus
MarkIPAsPendingRelease(numberToMark int) (map[string]IPConfigurationStatus, error)
Expand All @@ -54,7 +54,7 @@ type IPConfigurationStatus struct {
NCID string
ID string // uuid
IPAddress string
State IPConfigState
State types.IPState
PodInfo PodInfo
}

Expand Down Expand Up @@ -221,9 +221,9 @@ type IPAMPoolMonitor interface {

// IpamPoolMonitorStateSnapshot struct to expose state values for IPAMPoolMonitor struct
type IpamPoolMonitorStateSnapshot struct {
MinimumFreeIps int
MaximumFreeIps int
UpdatingIpsNotInUseCount int
MinimumFreeIps int64
MaximumFreeIps int64
UpdatingIpsNotInUseCount int64
CachedNNC v1alpha.NodeNetworkConfig
}

Expand Down
4 changes: 2 additions & 2 deletions cns/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ func (c *Client) ReleaseIPAddress(ctx context.Context, ipconfig cns.IPConfigRequ
}

// GetIPAddressesMatchingStates takes a variadic number of string parameters, to get all IP Addresses matching a number of states
// usage GetIPAddressesWithStates(cns.Available, cns.Allocated)
func (c *Client) GetIPAddressesMatchingStates(ctx context.Context, stateFilter ...cns.IPConfigState) ([]cns.IPConfigurationStatus, error) {
// usage GetIPAddressesWithStates(ctx, types.Available...)
func (c *Client) GetIPAddressesMatchingStates(ctx context.Context, stateFilter ...types.IPState) ([]cns.IPConfigurationStatus, error) {
if len(stateFilter) == 0 {
return nil, nil
}
Expand Down
28 changes: 14 additions & 14 deletions cns/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,13 @@ func TestCNSClientRequestAndRelease(t *testing.T) {

assert.Equal(t, desired, resultIPnet, "Desired result not matching actual result")

// checking for allocated IP address and pod context printing before ReleaseIPAddress is called
ipaddresses, err := cnsClient.GetIPAddressesMatchingStates(context.TODO(), cns.Allocated)
assert.NoError(t, err, "Get allocated IP addresses failed")
// checking for assigned IP address and pod context printing before ReleaseIPAddress is called
ipaddresses, err := cnsClient.GetIPAddressesMatchingStates(context.TODO(), types.Assigned)
assert.NoError(t, err, "Get assigned IP addresses failed")

assert.Len(t, ipaddresses, 1, "Number of available IP addresses expected to be 1")
assert.Equal(t, desiredIpAddress, ipaddresses[0].IPAddress, "Available IP address does not match expected, address state")
assert.Equal(t, cns.Allocated, ipaddresses[0].State, "Available IP address does not match expected, address state")
assert.Equal(t, types.Assigned, ipaddresses[0].State, "Available IP address does not match expected, address state")

t.Log(ipaddresses)

Expand Down Expand Up @@ -356,15 +356,15 @@ func TestCNSClientDebugAPI(t *testing.T) {
podConfig := inmemory.HTTPRestServiceData.PodIPConfigState
for _, v := range podConfig {
assert.Equal(t, "10.0.0.5", v.IPAddress, "Not the expected set values for testing IPConfigurationStatus, %+v", podConfig)
assert.Equal(t, cns.Allocated, v.State, "Not the expected set values for testing IPConfigurationStatus, %+v", podConfig)
assert.Equal(t, types.Assigned, v.State, "Not the expected set values for testing IPConfigurationStatus, %+v", podConfig)
assert.Equal(t, "testNcId1", v.NCID, "Not the expected set values for testing IPConfigurationStatus, %+v", podConfig)
}
assert.GreaterOrEqual(t, len(inmemory.HTTPRestServiceData.PodIPConfigState), 1, "PodIpConfigState with at least 1 entry expected")

testIpamPoolMonitor := inmemory.HTTPRestServiceData.IPAMPoolMonitor
assert.EqualValues(t, 5, testIpamPoolMonitor.MinimumFreeIps, "IPAMPoolMonitor state is not reflecting the initial set values")
assert.EqualValues(t, 15, testIpamPoolMonitor.MaximumFreeIps, "IPAMPoolMonitor state is not reflecting the initial set values")
assert.Equal(t, 13, testIpamPoolMonitor.UpdatingIpsNotInUseCount, "IPAMPoolMonitor state is not reflecting the initial set values")
assert.EqualValues(t, 13, testIpamPoolMonitor.UpdatingIpsNotInUseCount, "IPAMPoolMonitor state is not reflecting the initial set values")

// check for cached NNC Spec struct values
assert.EqualValues(t, 16, testIpamPoolMonitor.CachedNNC.Spec.RequestedIPCount, "IPAMPoolMonitor cached NNC Spec is not reflecting the initial set values")
Expand Down Expand Up @@ -1108,7 +1108,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
tests := []struct {
name string
ctx context.Context
stateFilter []cns.IPConfigState
stateFilter []types.IPState
mockdo *mockdo
routes map[string]url.URL
want []cns.IPConfigurationStatus
Expand All @@ -1117,7 +1117,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "happy case",
ctx: context.TODO(),
stateFilter: []cns.IPConfigState{cns.Available},
stateFilter: []types.IPState{types.Available},
mockdo: &mockdo{
errToReturn: nil,
objToReturn: &cns.GetIPAddressStatusResponse{
Expand All @@ -1132,7 +1132,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "length of zero",
ctx: context.TODO(),
stateFilter: []cns.IPConfigState{},
stateFilter: []types.IPState{},
mockdo: &mockdo{},
routes: emptyRoutes,
want: nil,
Expand All @@ -1141,7 +1141,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "bad request",
ctx: context.TODO(),
stateFilter: []cns.IPConfigState{"garbage"},
stateFilter: []types.IPState{"garbage"},
mockdo: &mockdo{
errToReturn: errBadRequest,
objToReturn: nil,
Expand All @@ -1154,7 +1154,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "bad decoding",
ctx: context.TODO(),
stateFilter: []cns.IPConfigState{cns.Available},
stateFilter: []types.IPState{types.Available},
mockdo: &mockdo{
errToReturn: nil,
objToReturn: []cns.GetIPAddressStatusResponse{},
Expand All @@ -1167,7 +1167,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "http status not ok",
ctx: context.TODO(),
stateFilter: []cns.IPConfigState{cns.Available},
stateFilter: []types.IPState{types.Available},
mockdo: &mockdo{
errToReturn: nil,
objToReturn: nil,
Expand All @@ -1180,7 +1180,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "cns return code not zero",
ctx: context.TODO(),
stateFilter: []cns.IPConfigState{cns.Available},
stateFilter: []types.IPState{types.Available},
mockdo: &mockdo{
errToReturn: nil,
objToReturn: &cns.GetIPAddressStatusResponse{
Expand All @@ -1197,7 +1197,7 @@ func TestGetIPAddressesMatchingStates(t *testing.T) {
{
name: "nil context",
ctx: nil,
stateFilter: []cns.IPConfigState{cns.Available},
stateFilter: []types.IPState{types.Available},
mockdo: &mockdo{},
routes: emptyRoutes,
wantErr: true,
Expand Down
32 changes: 13 additions & 19 deletions cns/cmd/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/client"
"github.com/Azure/azure-container-networking/cns/types"
)

const (
Expand Down Expand Up @@ -41,26 +42,19 @@ func HandleCNSClientCommands(ctx context.Context, cmd string, arg string) error
}

func getCmd(ctx context.Context, client *client.Client, arg string) error {
var states []cns.IPConfigState

switch cns.IPConfigState(arg) {
case cns.Available:
states = append(states, cns.Available)

case cns.Allocated:
states = append(states, cns.Allocated)

case cns.PendingRelease:
states = append(states, cns.PendingRelease)

case cns.PendingProgramming:
states = append(states, cns.PendingProgramming)

var states []types.IPState

switch types.IPState(arg) {
case types.Available:
states = append(states, types.Available)
case types.Assigned:
states = append(states, types.Assigned)
case types.PendingProgramming:
states = append(states, types.PendingProgramming)
case types.PendingRelease:
states = append(states, types.PendingRelease)
default:
states = append(states, cns.Allocated)
states = append(states, cns.Available)
states = append(states, cns.PendingRelease)
states = append(states, cns.PendingProgramming)
states = append(states, types.Assigned, types.Available, types.PendingProgramming, types.PendingRelease)
}

addr, err := client.GetIPAddressesMatchingStates(ctx, states...)
Expand Down
48 changes: 26 additions & 22 deletions cns/fakes/cnsfake.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (stack *StringStack) Pop() (string, error) {
type IPStateManager struct {
PendingProgramIPConfigState map[string]cns.IPConfigurationStatus
AvailableIPConfigState map[string]cns.IPConfigurationStatus
AllocatedIPConfigState map[string]cns.IPConfigurationStatus
AssignedIPConfigState map[string]cns.IPConfigurationStatus
PendingReleaseIPConfigState map[string]cns.IPConfigurationStatus
AvailableIPIDStack StringStack
sync.RWMutex
Expand All @@ -58,7 +58,7 @@ func NewIPStateManager() IPStateManager {
return IPStateManager{
PendingProgramIPConfigState: make(map[string]cns.IPConfigurationStatus),
AvailableIPConfigState: make(map[string]cns.IPConfigurationStatus),
AllocatedIPConfigState: make(map[string]cns.IPConfigurationStatus),
AssignedIPConfigState: make(map[string]cns.IPConfigurationStatus),
PendingReleaseIPConfigState: make(map[string]cns.IPConfigurationStatus),
AvailableIPIDStack: StringStack{},
}
Expand All @@ -69,14 +69,14 @@ func (ipm *IPStateManager) AddIPConfigs(ipconfigs []cns.IPConfigurationStatus) {
defer ipm.Unlock()
for _, ipconfig := range ipconfigs {
switch ipconfig.State {
case cns.PendingProgramming:
case types.PendingProgramming:
ipm.PendingProgramIPConfigState[ipconfig.ID] = ipconfig
case cns.Available:
case types.Available:
ipm.AvailableIPConfigState[ipconfig.ID] = ipconfig
ipm.AvailableIPIDStack.Push(ipconfig.ID)
case cns.Allocated:
ipm.AllocatedIPConfigState[ipconfig.ID] = ipconfig
case cns.PendingRelease:
case types.Assigned:
ipm.AssignedIPConfigState[ipconfig.ID] = ipconfig
case types.PendingRelease:
ipm.PendingReleaseIPConfigState[ipconfig.ID] = ipconfig
}
}
Expand All @@ -97,17 +97,21 @@ func (ipm *IPStateManager) ReserveIPConfig() (cns.IPConfigurationStatus, error)
if err != nil {
return cns.IPConfigurationStatus{}, err
}
ipm.AllocatedIPConfigState[id] = ipm.AvailableIPConfigState[id]
ipc := ipm.AvailableIPConfigState[id]
ipc.State = types.Assigned
ipm.AssignedIPConfigState[id] = ipc
delete(ipm.AvailableIPConfigState, id)
return ipm.AllocatedIPConfigState[id], nil
return ipm.AssignedIPConfigState[id], nil
}

func (ipm *IPStateManager) ReleaseIPConfig(ipconfigID string) (cns.IPConfigurationStatus, error) {
ipm.Lock()
defer ipm.Unlock()
ipm.AvailableIPConfigState[ipconfigID] = ipm.AllocatedIPConfigState[ipconfigID]
ipc := ipm.AssignedIPConfigState[ipconfigID]
ipc.State = types.Available
ipm.AvailableIPConfigState[ipconfigID] = ipc
ipm.AvailableIPIDStack.Push(ipconfigID)
delete(ipm.AllocatedIPConfigState, ipconfigID)
delete(ipm.AssignedIPConfigState, ipconfigID)
return ipm.AvailableIPConfigState[ipconfigID], nil
}

Expand All @@ -123,7 +127,7 @@ func (ipm *IPStateManager) MarkIPAsPendingRelease(numberOfIPsToMark int) (map[st
// if there was an error, and not all ip's have been freed, restore state
if err != nil && len(pendingReleaseIPs) != numberOfIPsToMark {
for uuid, ipState := range pendingReleaseIPs {
ipState.State = cns.Available
ipState.State = types.Available
ipm.AvailableIPIDStack.Push(pendingReleaseIPs[uuid].ID)
ipm.AvailableIPConfigState[pendingReleaseIPs[uuid].ID] = ipState
delete(ipm.PendingReleaseIPConfigState, pendingReleaseIPs[uuid].ID)
Expand All @@ -139,7 +143,7 @@ func (ipm *IPStateManager) MarkIPAsPendingRelease(numberOfIPsToMark int) (map[st

// add all pending release to a slice
ipConfig := ipm.AvailableIPConfigState[id]
ipConfig.State = cns.PendingRelease
ipConfig.State = types.PendingRelease
pendingReleaseIPs[id] = ipConfig

delete(ipm.AvailableIPConfigState, id)
Expand All @@ -166,23 +170,23 @@ func NewHTTPServiceFake() *HTTPServiceFake {
}
}

func (fake *HTTPServiceFake) SetNumberOfAllocatedIPs(desiredAllocatedIPCount int) error {
currentAllocatedIPCount := len(fake.IPStateManager.AllocatedIPConfigState)
delta := (desiredAllocatedIPCount - currentAllocatedIPCount)
func (fake *HTTPServiceFake) SetNumberOfAssignedIPs(assign int) error {
currentAssigned := len(fake.IPStateManager.AssignedIPConfigState)
delta := (assign - currentAssigned)

if delta > 0 {
// allocated IPs
// assign IPs
for i := 0; i < delta; i++ {
if _, err := fake.IPStateManager.ReserveIPConfig(); err != nil {
return err
}
}
return nil
}
// deallocate IPs
// unassign IPs
delta *= -1
i := 0
for id := range fake.IPStateManager.AllocatedIPConfigState {
for id := range fake.IPStateManager.AssignedIPConfigState {
if i >= delta {
break
}
Expand Down Expand Up @@ -221,9 +225,9 @@ func (fake *HTTPServiceFake) GetAvailableIPConfigs() []cns.IPConfigurationStatus
return ipconfigs
}

func (fake *HTTPServiceFake) GetAllocatedIPConfigs() []cns.IPConfigurationStatus {
func (fake *HTTPServiceFake) GetAssignedIPConfigs() []cns.IPConfigurationStatus {
ipconfigs := []cns.IPConfigurationStatus{}
for _, ipconfig := range fake.IPStateManager.AllocatedIPConfigState {
for _, ipconfig := range fake.IPStateManager.AssignedIPConfigState {
ipconfigs = append(ipconfigs, ipconfig)
}
return ipconfigs
Expand All @@ -240,7 +244,7 @@ func (fake *HTTPServiceFake) GetPendingReleaseIPConfigs() []cns.IPConfigurationS
// Return union of all state maps
func (fake *HTTPServiceFake) GetPodIPConfigState() map[string]cns.IPConfigurationStatus {
ipconfigs := make(map[string]cns.IPConfigurationStatus)
for key, val := range fake.IPStateManager.AllocatedIPConfigState {
for key, val := range fake.IPStateManager.AssignedIPConfigState {
ipconfigs[key] = val
}
for key, val := range fake.IPStateManager.AvailableIPConfigState {
Expand Down
6 changes: 3 additions & 3 deletions cns/fakes/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

type MonitorFake struct {
IPsNotInUseCount int
IPsNotInUseCount int64
NodeNetworkConfig *v1alpha.NodeNetworkConfig
}

Expand All @@ -29,8 +29,8 @@ func (*MonitorFake) Reconcile() error {

func (f *MonitorFake) GetStateSnapshot() cns.IpamPoolMonitorStateSnapshot {
return cns.IpamPoolMonitorStateSnapshot{
MaximumFreeIps: int(float64(f.NodeNetworkConfig.Status.Scaler.BatchSize) * (float64(f.NodeNetworkConfig.Status.Scaler.ReleaseThresholdPercent) / 100)), //nolint:gomnd // it's a percent
MinimumFreeIps: int(float64(f.NodeNetworkConfig.Status.Scaler.BatchSize) * (float64(f.NodeNetworkConfig.Status.Scaler.RequestThresholdPercent) / 100)), //nolint:gomnd // it's a percent
MaximumFreeIps: int64(float64(f.NodeNetworkConfig.Status.Scaler.BatchSize) * (float64(f.NodeNetworkConfig.Status.Scaler.ReleaseThresholdPercent) / 100)), //nolint:gomnd // it's a percent
MinimumFreeIps: int64(float64(f.NodeNetworkConfig.Status.Scaler.BatchSize) * (float64(f.NodeNetworkConfig.Status.Scaler.RequestThresholdPercent) / 100)), //nolint:gomnd // it's a percent
UpdatingIpsNotInUseCount: f.IPsNotInUseCount,
CachedNNC: *f.NodeNetworkConfig,
}
Expand Down
Loading