Skip to content

Commit 903b482

Browse files
committed
add dualnic windows multitenancy test
1 parent 3ed0bcd commit 903b482

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

cni/network/network_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func setNetworkOptions(cnsNwConfig *cns.GetNetworkContainerResponse, nwInfo *net
4646
}
4747
}
4848

49+
// update epInfo data field, allow host to nc, allow nc to host, and network container id
4950
func setEndpointOptions(cnsNwConfig *cns.GetNetworkContainerResponse, epInfo *network.EndpointInfo, vethName string) {
5051
if cnsNwConfig != nil && cnsNwConfig.MultiTenancyInfo.ID != 0 {
5152
logger.Info("Setting Endpoint Options")

cni/network/network_windows_test.go

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import (
77
"encoding/json"
88
"fmt"
99
"net"
10+
"regexp"
1011
"testing"
1112

1213
"github.com/Azure/azure-container-networking/cni"
1314
"github.com/Azure/azure-container-networking/cns"
1415
"github.com/Azure/azure-container-networking/network"
1516
"github.com/Azure/azure-container-networking/network/hnswrapper"
1617
"github.com/Azure/azure-container-networking/network/policy"
18+
"github.com/Azure/azure-container-networking/platform"
1719
"github.com/Azure/azure-container-networking/telemetry"
1820
hnsv2 "github.com/Microsoft/hcsshim/hcn"
1921
cniSkel "github.com/containernetworking/cni/pkg/skel"
@@ -855,3 +857,182 @@ func TestPluginMultitenancyWindowsDelete(t *testing.T) {
855857
})
856858
}
857859
}
860+
861+
// Happy path scenario for add and delete
862+
func TestPluginWindowsAdd(t *testing.T) {
863+
resources := GetTestResources()
864+
localNwCfg := cni.NetworkConfig{
865+
CNIVersion: "0.3.0",
866+
Name: "mulnet",
867+
MultiTenancy: true,
868+
EnableExactMatchForPodName: true,
869+
Master: "eth0",
870+
}
871+
type endpointEntry struct {
872+
epInfo *network.EndpointInfo
873+
epIDRegex string
874+
}
875+
876+
tests := []struct {
877+
name string
878+
plugin *NetPlugin
879+
args *cniSkel.CmdArgs
880+
want []endpointEntry
881+
match func(*network.EndpointInfo, *network.EndpointInfo) bool
882+
}{
883+
{
884+
name: "Add Happy Path Dual NIC",
885+
plugin: &NetPlugin{
886+
Plugin: resources.Plugin,
887+
nm: network.NewMockNetworkmanager(network.NewMockEndpointClient(nil)),
888+
tb: &telemetry.TelemetryBuffer{},
889+
report: &telemetry.CNIReport{},
890+
multitenancyClient: NewMockMultitenancy(false, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1(), GetTestCNSResponse2()}),
891+
},
892+
args: &cniSkel.CmdArgs{
893+
StdinData: localNwCfg.Serialize(),
894+
ContainerID: "test-container",
895+
Netns: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
896+
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
897+
IfName: eth0IfName,
898+
},
899+
match: func(ei1, ei2 *network.EndpointInfo) bool {
900+
return ei1.NetworkID == ei2.NetworkID
901+
},
902+
want: []endpointEntry{
903+
// should match with GetTestCNSResponse1
904+
{
905+
epInfo: &network.EndpointInfo{
906+
ContainerID: "test-container",
907+
Data: map[string]interface{}{
908+
"cnetAddressSpace": ([]string)(nil),
909+
},
910+
Routes: []network.RouteInfo{},
911+
EnableSnatOnHost: true,
912+
EnableMultiTenancy: true,
913+
EnableSnatForDns: true,
914+
PODName: "test-pod",
915+
PODNameSpace: "test-pod-ns",
916+
NICType: cns.InfraNIC,
917+
MasterIfName: eth0IfName,
918+
NetworkID: "mulnet-vlan1-20-0-0-0_24",
919+
NetNsPath: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
920+
NetNs: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
921+
HostSubnetPrefix: "20.240.0.0/24",
922+
Options: map[string]interface{}{
923+
dockerNetworkOption: map[string]interface{}{
924+
"VlanID": "1",
925+
},
926+
},
927+
// matches with cns ip configuration
928+
IPAddresses: []net.IPNet{
929+
{
930+
IP: net.ParseIP("20.0.0.10"),
931+
Mask: getIPNetWithString("20.0.0.10/24").Mask,
932+
},
933+
},
934+
// LocalIPConfiguration doesn't seem used in windows
935+
// Constant, in windows, NAT Info comes from
936+
// options > ipamAddConfig >
937+
// cns invoker may populate network.SNATIPKey with the default response received >
938+
// getNATInfo (with nwCfg) > adds nat info based on condition
939+
// typically adds azure dns (168.63.129.16)
940+
NATInfo: []policy.NATInfo{
941+
{
942+
Destinations: []string{"168.63.129.16"},
943+
},
944+
},
945+
// ip config pod ip + mask(s) from cns > interface info > subnet info
946+
Subnets: []network.SubnetInfo{
947+
{
948+
Family: platform.AfINET,
949+
// matches cns ip configuration (20.0.0.1/24 == 20.0.0.0/24)
950+
Prefix: *getIPNetWithString("20.0.0.0/24"),
951+
// matches cns ip configuration gateway ip address
952+
Gateway: net.ParseIP("20.0.0.1"),
953+
},
954+
},
955+
},
956+
epIDRegex: `.*`,
957+
},
958+
// should match with GetTestCNSResponse2
959+
{
960+
epInfo: &network.EndpointInfo{
961+
ContainerID: "test-container",
962+
Data: map[string]interface{}{
963+
"cnetAddressSpace": ([]string)(nil),
964+
},
965+
Routes: []network.RouteInfo{},
966+
EnableSnatOnHost: true,
967+
EnableMultiTenancy: true,
968+
EnableSnatForDns: true,
969+
PODName: "test-pod",
970+
PODNameSpace: "test-pod-ns",
971+
NICType: cns.InfraNIC,
972+
MasterIfName: eth0IfName,
973+
NetworkID: "mulnet-vlan2-10-0-0-0_24",
974+
NetNsPath: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
975+
NetNs: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
976+
HostSubnetPrefix: "10.240.0.0/24",
977+
Options: map[string]interface{}{
978+
dockerNetworkOption: map[string]interface{}{
979+
"VlanID": "2",
980+
},
981+
},
982+
IPAddresses: []net.IPNet{
983+
{
984+
IP: net.ParseIP("10.0.0.10"),
985+
Mask: getIPNetWithString("10.0.0.10/24").Mask,
986+
},
987+
},
988+
NATInfo: []policy.NATInfo{
989+
{
990+
Destinations: []string{"168.63.129.16"},
991+
},
992+
},
993+
Subnets: []network.SubnetInfo{
994+
{
995+
Family: platform.AfINET,
996+
Prefix: *getIPNetWithString("10.0.0.0/24"),
997+
Gateway: net.ParseIP("10.0.0.1"),
998+
},
999+
},
1000+
},
1001+
epIDRegex: `.*`,
1002+
},
1003+
},
1004+
},
1005+
}
1006+
1007+
for _, tt := range tests {
1008+
tt := tt
1009+
t.Run(tt.name, func(t *testing.T) {
1010+
err := tt.plugin.Add(tt.args)
1011+
require.NoError(t, err)
1012+
allEndpoints, _ := tt.plugin.nm.GetAllEndpoints("")
1013+
require.Len(t, allEndpoints, len(tt.want))
1014+
for _, wantedEndpointEntry := range tt.want {
1015+
epId := "none"
1016+
for _, endpointInfo := range allEndpoints {
1017+
if tt.match(wantedEndpointEntry.epInfo, endpointInfo) {
1018+
// save the endpoint id before removing it
1019+
epId = endpointInfo.EndpointID
1020+
require.Regexp(t, regexp.MustCompile(wantedEndpointEntry.epIDRegex), epId)
1021+
1022+
// omit endpoint id and ifname fields as they are nondeterministic
1023+
endpointInfo.EndpointID = ""
1024+
endpointInfo.IfName = ""
1025+
1026+
require.Equal(t, wantedEndpointEntry.epInfo, endpointInfo)
1027+
break
1028+
}
1029+
}
1030+
if epId == "none" {
1031+
t.Fail()
1032+
}
1033+
tt.plugin.nm.DeleteEndpoint("", epId, nil)
1034+
}
1035+
1036+
})
1037+
}
1038+
}

0 commit comments

Comments
 (0)