Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NPM Lite] Support Network Policies Through CNS #3287

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions cni/network/invoker_cns.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/Azure/azure-container-networking/iptables"
"github.com/Azure/azure-container-networking/network"
"github.com/Azure/azure-container-networking/network/networkutils"
"github.com/Azure/azure-container-networking/network/policy"
cniSkel "github.com/containernetworking/cni/pkg/skel"
"github.com/pkg/errors"
"go.uber.org/zap"
Expand Down Expand Up @@ -55,6 +56,7 @@ type IPResultInfo struct {
skipDefaultRoutes bool
routes []cns.Route
pnpID string
endpointPolicies []policy.Policy
}

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

logger.Info("Received info for pod",
Expand Down Expand Up @@ -444,6 +447,7 @@ func configureDefaultAddResult(info *IPResultInfo, addConfig *IPAMAddConfig, add
Gw: ncgw,
})
}

// if we have multiple infra ip result infos, we effectively append routes and ip configs to that same interface info each time
// the host subnet prefix (in ipv4 or ipv6) will always refer to the same interface regardless of which ip result info we look at
addResult.interfaceInfo[key] = network.InterfaceInfo{
Expand All @@ -452,6 +456,7 @@ func configureDefaultAddResult(info *IPResultInfo, addConfig *IPAMAddConfig, add
IPConfigs: ipConfigs,
Routes: resRoute,
HostSubnetPrefix: *hostIPNet,
EndpointPolicies: info.endpointPolicies,
}
}

Expand Down
81 changes: 66 additions & 15 deletions cni/network/invoker_cns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/iptables"
"github.com/Azure/azure-container-networking/network"
"github.com/Azure/azure-container-networking/network/policy"
cniSkel "github.com/containernetworking/cni/pkg/skel"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -521,14 +522,38 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
hostSubnetPrefix *net.IPNet
options map[string]interface{}
}
valueOut := []byte(`{
"Type": "ACL",
"Action": "Block",
"Direction": "Out",
"Priority": 10000
}`)

valueIn := []byte(`{
"Type": "ACL",
"Action": "Block",
"Direction": "In",
"Priority": 10000
}`)

expectedEndpointPolicies := []policy.Policy{
{
Type: policy.EndpointPolicy,
Data: valueOut,
},
{
Type: policy.EndpointPolicy,
Data: valueIn,
},
}
tests := []struct {
name string
fields fields
args args
wantDefaultResult network.InterfaceInfo
wantMultitenantResult network.InterfaceInfo
wantErr bool
name string
fields fields
args args
wantDefaultDenyEndpoints bool
wantDefaultResult network.InterfaceInfo
wantMultitenantResult network.InterfaceInfo
wantErr bool
}{
{
name: "Test happy CNI add",
Expand Down Expand Up @@ -559,7 +584,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
PrimaryIP: "10.0.0.1",
Subnet: "10.0.0.0/24",
},
NICType: cns.InfraNIC,
NICType: cns.InfraNIC,
EndpointPolicies: expectedEndpointPolicies,
},
},
Response: cns.Response{
Expand Down Expand Up @@ -588,6 +614,7 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
Gateway: net.ParseIP("10.0.0.1"),
},
},
EndpointPolicies: expectedEndpointPolicies,
Routes: []network.RouteInfo{
{
Dst: network.Ipv4DefaultRouteDstPrefix,
Expand All @@ -597,7 +624,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
NICType: cns.InfraNIC,
HostSubnetPrefix: *parseCIDR("10.0.0.0/24"),
},
wantErr: false,
wantDefaultDenyEndpoints: true,
wantErr: false,
},
{
name: "Test CNI add with pod ip info empty nictype",
Expand Down Expand Up @@ -665,7 +693,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
NICType: cns.InfraNIC,
HostSubnetPrefix: *parseCIDR("10.0.0.0/24"),
},
wantErr: false,
wantDefaultDenyEndpoints: false,
wantErr: false,
},
{
name: "Test happy CNI add for both ipv4 and ipv6",
Expand Down Expand Up @@ -696,7 +725,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
PrimaryIP: "10.0.0.1",
Subnet: "10.0.0.0/24",
},
NICType: cns.InfraNIC,
NICType: cns.InfraNIC,
EndpointPolicies: expectedEndpointPolicies,
},
{
PodIPConfig: cns.IPSubnet{
Expand All @@ -716,7 +746,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
PrimaryIP: "fe80::1234:5678:9abc",
Subnet: "fd11:1234::/112",
},
NICType: cns.InfraNIC,
NICType: cns.InfraNIC,
EndpointPolicies: expectedEndpointPolicies,
},
},
Response: cns.Response{
Expand Down Expand Up @@ -749,6 +780,7 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
Gateway: net.ParseIP("fe80::1234:5678:9abc"),
},
},
EndpointPolicies: expectedEndpointPolicies,
Routes: []network.RouteInfo{
{
Dst: network.Ipv4DefaultRouteDstPrefix,
Expand All @@ -762,7 +794,8 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
NICType: cns.InfraNIC,
HostSubnetPrefix: *parseCIDR("fd11:1234::/112"),
},
wantErr: false,
wantDefaultDenyEndpoints: true,
wantErr: false,
},
{
name: "fail to request IP addresses from cns",
Expand All @@ -773,12 +806,24 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
require: require,
requestIPs: requestIPsHandler{
ipconfigArgument: getTestIPConfigsRequest(),
result: nil,
err: errors.New("failed error from CNS"), //nolint "error for ut"
result: &cns.IPConfigsResponse{
PodIPInfo: []cns.PodIpInfo{
{
EndpointPolicies: expectedEndpointPolicies,
},
},
Response: cns.Response{
ReturnCode: 0,
Message: "",
},
},
err: errors.New("failed error from CNS"), //nolint "error for ut"
paulyufan2 marked this conversation as resolved.
Show resolved Hide resolved

},
},
},
wantErr: true,
wantDefaultDenyEndpoints: false,
wantErr: true,
},
}
for _, tt := range tests {
Expand All @@ -794,6 +839,7 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
}
ipamAddResult, err := invoker.Add(IPAMAddConfig{nwCfg: tt.args.nwCfg, args: tt.args.args, options: tt.args.options})
if tt.wantErr {
require.Equalf([]policy.Policy(nil), ipamAddResult.interfaceInfo[string(cns.InfraNIC)].EndpointPolicies, "There was an error requesting IP addresses from cns")
require.Error(err)
} else {
require.NoError(err)
Expand All @@ -809,6 +855,11 @@ func TestCNSIPAMInvoker_Add(t *testing.T) {
}
if ifInfo.NICType == cns.InfraNIC {
require.Equalf(tt.wantDefaultResult, ifInfo, "incorrect default response")
if tt.wantDefaultDenyEndpoints {
require.Equalf(expectedEndpointPolicies, ifInfo.EndpointPolicies, "Correct default deny ACL")
} else {
require.Equalf([]policy.Policy(nil), ifInfo.EndpointPolicies, "Correct default deny ACL")
}
}
}
})
Expand Down
5 changes: 5 additions & 0 deletions cni/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,11 @@ func (plugin *NetPlugin) Add(args *cniSkel.CmdArgs) error {
}

policies := cni.GetPoliciesFromNwCfg(nwCfg.AdditionalArgs)
for key := range ipamAddResult.interfaceInfo {
paulyufan2 marked this conversation as resolved.
Show resolved Hide resolved
if key == string(cns.InfraNIC) {
rejain456 marked this conversation as resolved.
Show resolved Hide resolved
policies = append(policies, ipamAddResult.interfaceInfo[key].EndpointPolicies...)
}
}
// moved to addIpamInvoker
// sendEvent(plugin, fmt.Sprintf("Allocated IPAddress from ipam interface: %+v", ipamAddResult.PrettyString()))

Expand Down
3 changes: 3 additions & 0 deletions cns/NetworkContainerContract.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/types"
"github.com/Azure/azure-container-networking/crd/nodenetworkconfig/api/v1alpha"
"github.com/Azure/azure-container-networking/network/policy"
"github.com/google/uuid"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -503,6 +504,8 @@ type PodIpInfo struct {
Routes []Route
// PnpId is set for backend interfaces, Pnp Id identifies VF. Plug and play id(pnp) is also called as PCI ID
PnPID string
// Default Deny ACL's to configure on HNS endpoints for Swiftv2 window nodes
EndpointPolicies []policy.Policy
}

type HostIPInfo struct {
Expand Down
1 change: 1 addition & 0 deletions network/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ type InterfaceInfo struct {
HostSubnetPrefix net.IPNet // Move this field from ipamAddResult
NCResponse *cns.GetNetworkContainerResponse
PnPID string
EndpointPolicies []policy.Policy
}

type IPConfig struct {
Expand Down
Loading