Skip to content

Commit a8f22ee

Browse files
authored
[NPM Lite] Support Network Policies Through CNS (#3287)
* added npm lite default deny cni changes * added changes for unit tests * fixed test message * moved default deny acl under interfaceinfo * reverted a change in network * removed a logging line * added a new line * updated unit test * moved cni kv pair to common folder * updated cni code to match network container contract update * updated unit test case * updated unit test to add cns not sending default deny acl to cni * removed an infra nic check * removed an infra nic check * removed for loop * removed an extra spacing * update from pr comment * updated unit test * updated unit tests * fixed golint
1 parent a1b4d10 commit a8f22ee

File tree

5 files changed

+102
-15
lines changed

5 files changed

+102
-15
lines changed

cni/network/invoker_cns.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/Azure/azure-container-networking/iptables"
1616
"github.com/Azure/azure-container-networking/network"
1717
"github.com/Azure/azure-container-networking/network/networkutils"
18+
"github.com/Azure/azure-container-networking/network/policy"
1819
cniSkel "github.com/containernetworking/cni/pkg/skel"
1920
"github.com/pkg/errors"
2021
"go.uber.org/zap"
@@ -55,6 +56,7 @@ type IPResultInfo struct {
5556
skipDefaultRoutes bool
5657
routes []cns.Route
5758
pnpID string
59+
endpointPolicies []policy.Policy
5860
}
5961

6062
func (i IPResultInfo) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
@@ -159,6 +161,7 @@ func (invoker *CNSIPAMInvoker) Add(addConfig IPAMAddConfig) (IPAMAddResult, erro
159161
skipDefaultRoutes: response.PodIPInfo[i].SkipDefaultRoutes,
160162
routes: response.PodIPInfo[i].Routes,
161163
pnpID: response.PodIPInfo[i].PnPID,
164+
endpointPolicies: response.PodIPInfo[i].EndpointPolicies,
162165
}
163166

164167
logger.Info("Received info for pod",
@@ -444,6 +447,7 @@ func configureDefaultAddResult(info *IPResultInfo, addConfig *IPAMAddConfig, add
444447
Gw: ncgw,
445448
})
446449
}
450+
447451
// if we have multiple infra ip result infos, we effectively append routes and ip configs to that same interface info each time
448452
// the host subnet prefix (in ipv4 or ipv6) will always refer to the same interface regardless of which ip result info we look at
449453
addResult.interfaceInfo[key] = network.InterfaceInfo{
@@ -452,6 +456,7 @@ func configureDefaultAddResult(info *IPResultInfo, addConfig *IPAMAddConfig, add
452456
IPConfigs: ipConfigs,
453457
Routes: resRoute,
454458
HostSubnetPrefix: *hostIPNet,
459+
EndpointPolicies: info.endpointPolicies,
455460
}
456461
}
457462

cni/network/invoker_cns_test.go

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/Azure/azure-container-networking/cns"
1313
"github.com/Azure/azure-container-networking/iptables"
1414
"github.com/Azure/azure-container-networking/network"
15+
"github.com/Azure/azure-container-networking/network/policy"
1516
cniSkel "github.com/containernetworking/cni/pkg/skel"
1617
"github.com/stretchr/testify/require"
1718
)
@@ -521,14 +522,38 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
521522
hostSubnetPrefix *net.IPNet
522523
options map[string]interface{}
523524
}
525+
valueOut := []byte(`{
526+
"Type": "ACL",
527+
"Action": "Block",
528+
"Direction": "Out",
529+
"Priority": 10000
530+
}`)
524531

532+
valueIn := []byte(`{
533+
"Type": "ACL",
534+
"Action": "Block",
535+
"Direction": "In",
536+
"Priority": 10000
537+
}`)
538+
539+
expectedEndpointPolicies := []policy.Policy{
540+
{
541+
Type: policy.EndpointPolicy,
542+
Data: valueOut,
543+
},
544+
{
545+
Type: policy.EndpointPolicy,
546+
Data: valueIn,
547+
},
548+
}
525549
tests := []struct {
526-
name string
527-
fields fields
528-
args args
529-
wantDefaultResult network.InterfaceInfo
530-
wantMultitenantResult network.InterfaceInfo
531-
wantErr bool
550+
name string
551+
fields fields
552+
args args
553+
wantDefaultDenyEndpoints bool
554+
wantDefaultResult network.InterfaceInfo
555+
wantMultitenantResult network.InterfaceInfo
556+
wantErr bool
532557
}{
533558
{
534559
name: "Test happy CNI add",
@@ -559,7 +584,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
559584
PrimaryIP: "10.0.0.1",
560585
Subnet: "10.0.0.0/24",
561586
},
562-
NICType: cns.InfraNIC,
587+
NICType: cns.InfraNIC,
588+
EndpointPolicies: expectedEndpointPolicies,
563589
},
564590
},
565591
Response: cns.Response{
@@ -588,6 +614,7 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
588614
Gateway: net.ParseIP("10.0.0.1"),
589615
},
590616
},
617+
EndpointPolicies: expectedEndpointPolicies,
591618
Routes: []network.RouteInfo{
592619
{
593620
Dst: network.Ipv4DefaultRouteDstPrefix,
@@ -597,7 +624,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
597624
NICType: cns.InfraNIC,
598625
HostSubnetPrefix: *parseCIDR("10.0.0.0/24"),
599626
},
600-
wantErr: false,
627+
wantDefaultDenyEndpoints: true,
628+
wantErr: false,
601629
},
602630
{
603631
name: "Test CNI add with pod ip info empty nictype",
@@ -665,7 +693,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
665693
NICType: cns.InfraNIC,
666694
HostSubnetPrefix: *parseCIDR("10.0.0.0/24"),
667695
},
668-
wantErr: false,
696+
wantDefaultDenyEndpoints: false,
697+
wantErr: false,
669698
},
670699
{
671700
name: "Test happy CNI add for both ipv4 and ipv6",
@@ -696,7 +725,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
696725
PrimaryIP: "10.0.0.1",
697726
Subnet: "10.0.0.0/24",
698727
},
699-
NICType: cns.InfraNIC,
728+
NICType: cns.InfraNIC,
729+
EndpointPolicies: expectedEndpointPolicies,
700730
},
701731
{
702732
PodIPConfig: cns.IPSubnet{
@@ -716,7 +746,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
716746
PrimaryIP: "fe80::1234:5678:9abc",
717747
Subnet: "fd11:1234::/112",
718748
},
719-
NICType: cns.InfraNIC,
749+
NICType: cns.InfraNIC,
750+
EndpointPolicies: expectedEndpointPolicies,
720751
},
721752
},
722753
Response: cns.Response{
@@ -749,6 +780,7 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
749780
Gateway: net.ParseIP("fe80::1234:5678:9abc"),
750781
},
751782
},
783+
EndpointPolicies: expectedEndpointPolicies,
752784
Routes: []network.RouteInfo{
753785
{
754786
Dst: network.Ipv4DefaultRouteDstPrefix,
@@ -762,7 +794,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
762794
NICType: cns.InfraNIC,
763795
HostSubnetPrefix: *parseCIDR("fd11:1234::/112"),
764796
},
765-
wantErr: false,
797+
wantDefaultDenyEndpoints: true,
798+
wantErr: false,
766799
},
767800
{
768801
name: "fail to request IP addresses from cns",
@@ -773,12 +806,24 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
773806
require: require,
774807
requestIPs: requestIPsHandler{
775808
ipconfigArgument: getTestIPConfigsRequest(),
776-
result: nil,
777-
err: errors.New("failed error from CNS"), //nolint "error for ut"
809+
result: &cns.IPConfigsResponse{
810+
PodIPInfo: []cns.PodIpInfo{
811+
{
812+
EndpointPolicies: expectedEndpointPolicies,
813+
},
814+
},
815+
Response: cns.Response{
816+
ReturnCode: 0,
817+
Message: "",
818+
},
819+
},
820+
err: errors.New("failed error from CNS"), //nolint "error for ut"
821+
778822
},
779823
},
780824
},
781-
wantErr: true,
825+
wantDefaultDenyEndpoints: false,
826+
wantErr: true,
782827
},
783828
}
784829
for _, tt := range tests {
@@ -794,6 +839,7 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
794839
}
795840
ipamAddResult, err := invoker.Add(IPAMAddConfig{nwCfg: tt.args.nwCfg, args: tt.args.args, options: tt.args.options})
796841
if tt.wantErr {
842+
require.Equalf([]policy.Policy(nil), ipamAddResult.interfaceInfo[string(cns.InfraNIC)].EndpointPolicies, "There was an error requesting IP addresses from cns")
797843
require.Error(err)
798844
} else {
799845
require.NoError(err)
@@ -809,6 +855,11 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
809855
}
810856
if ifInfo.NICType == cns.InfraNIC {
811857
require.Equalf(tt.wantDefaultResult, ifInfo, "incorrect default response")
858+
if tt.wantDefaultDenyEndpoints {
859+
require.Equalf(expectedEndpointPolicies, ifInfo.EndpointPolicies, "Correct default deny ACL")
860+
} else {
861+
require.Equalf([]policy.Policy(nil), ifInfo.EndpointPolicies, "Correct default deny ACL")
862+
}
812863
}
813864
}
814865
})

cni/network/network.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,10 @@ func (plugin *NetPlugin) createEpInfo(opt *createEpInfoOpt) (*network.EndpointIn
833833
// create endpoint policies by appending to network policies
834834
// the value passed into NetworkPolicies should be unaffected since we reassign here
835835
opt.policies = append(opt.policies, endpointPolicies...)
836+
837+
// appends endpoint policies specific to this interface
838+
opt.policies = append(opt.policies, opt.ifInfo.EndpointPolicies...)
839+
836840
endpointInfo.EndpointPolicies = opt.policies
837841
// add even more endpoint policies
838842
epPolicies, err := getPoliciesFromRuntimeCfg(opt.nwCfg, opt.ipamAddResult.ipv6Enabled) // not specific to delegated or infra

cni/network/network_windows_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,12 @@ func GetTestCNSResponseSecondaryWindows(macAddress string) map[string]network.In
878878
SkipDefaultRoutes: true,
879879
NICType: cns.InfraNIC,
880880
HostSubnetPrefix: *getCIDRNotationForAddress("20.224.0.0/16"),
881+
EndpointPolicies: []policy.Policy{
882+
{
883+
Type: policy.EndpointPolicy,
884+
Data: GetRawACLPolicy(),
885+
},
886+
},
881887
},
882888
macAddress: {
883889
MacAddress: parsedMAC,
@@ -895,6 +901,12 @@ func GetTestCNSResponseSecondaryWindows(macAddress string) map[string]network.In
895901
},
896902
},
897903
NICType: cns.NodeNetworkInterfaceFrontendNIC,
904+
EndpointPolicies: []policy.Policy{
905+
{
906+
Type: policy.EndpointPolicy,
907+
Data: GetRawOutBoundNATPolicy(),
908+
},
909+
},
898910
},
899911
}
900912
}
@@ -1226,6 +1238,12 @@ func TestPluginWindowsAdd(t *testing.T) {
12261238
Gateway: net.ParseIP("10.244.2.1"),
12271239
},
12281240
},
1241+
EndpointPolicies: []policy.Policy{
1242+
{
1243+
Type: policy.EndpointPolicy,
1244+
Data: GetRawACLPolicy(),
1245+
},
1246+
},
12291247
},
12301248
epIDRegex: `.*`,
12311249
},
@@ -1269,6 +1287,12 @@ func TestPluginWindowsAdd(t *testing.T) {
12691287
Gateway: net.ParseIP("10.241.0.1"),
12701288
},
12711289
},
1290+
EndpointPolicies: []policy.Policy{
1291+
{
1292+
Type: policy.EndpointPolicy,
1293+
Data: GetRawOutBoundNATPolicy(),
1294+
},
1295+
},
12721296
},
12731297
epIDRegex: `.*`,
12741298
},
@@ -1326,6 +1350,8 @@ func TestPluginWindowsAdd(t *testing.T) {
13261350
epInfo1.EndpointPolicies[0] = policy.Policy{
13271351
Type: policy.ACLPolicy,
13281352
}
1353+
require.Len(t, epInfo1.EndpointPolicies, 1)
1354+
require.Len(t, epInfo2.EndpointPolicies, 1)
13291355
require.NotEqual(t, epInfo1.EndpointPolicies, epInfo2.EndpointPolicies)
13301356
}
13311357
// ensure the network policy slices are separate entities when in separate endpoint infos

network/endpoint.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ type InterfaceInfo struct {
138138
HostSubnetPrefix net.IPNet // Move this field from ipamAddResult
139139
NCResponse *cns.GetNetworkContainerResponse
140140
PnPID string
141+
EndpointPolicies []policy.Policy
141142
}
142143

143144
type IPConfig struct {

0 commit comments

Comments
 (0)