Skip to content

Commit 4d27a9f

Browse files
author
Sotiris Nanopoulos
authored
feat: Adds support for HNS L4WFPProxyPolicy (#1003)
Fixes #1002 Allow the cni plugin to marshall and apply L4WFPProxyPolicy to Windows endpoints. Tested on Kubernetes v1.19 with AKS-engine and docker/containerd runtime Signed-off-by: Sotiris Nanopoulos <[email protected]>
1 parent 1eb5a80 commit 4d27a9f

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

network/policy/policy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const (
1111
RoutePolicy CNIPolicyType = "ROUTE"
1212
PortMappingPolicy CNIPolicyType = "NAT"
1313
ACLPolicy CNIPolicyType = "ACL"
14+
L4WFPProxyPolicy CNIPolicyType = "L4WFPPROXY"
1415
)
1516

1617
type CNIPolicyType string

network/policy/policy_windows.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ type KVPairRoute struct {
3737
NeedEncap bool `json:"NeedEncap"`
3838
}
3939

40+
type KVPairL4WfpProxyPolicy struct {
41+
Type CNIPolicyType `json:"Type"`
42+
OutboundProxyPort string `json:"OutboundProxyPort"`
43+
InboundProxyPort string `json:"InboundProxyPort"`
44+
UserSID string `json:"UserSID"`
45+
FilterTuple json.RawMessage `json:"FilterTuple"`
46+
InboundExceptions json.RawMessage `json:"InboundExceptions"`
47+
OutboundExceptions json.RawMessage `json:"OutboundExceptions"`
48+
}
49+
4050
var ValidWinVerForDnsNat bool
4151

4252
// SerializePolicies serializes policies to json.
@@ -206,6 +216,14 @@ func GetPolicyType(policy Policy) CNIPolicyType {
206216
}
207217
}
208218

219+
// Check if the type is L4WFPProxy
220+
var l4WfpProxyPolicy KVPairL4WfpProxyPolicy
221+
if err := json.Unmarshal(policy.Data, &l4WfpProxyPolicy); err == nil {
222+
if l4WfpProxyPolicy.Type == L4WFPProxyPolicy {
223+
return L4WFPProxyPolicy
224+
}
225+
}
226+
209227
// Check if the type if Port mapping / NAT
210228
var dataPortMapping hcn.EndpointPolicy
211229
if err := json.Unmarshal(policy.Data, &dataPortMapping); err == nil {
@@ -386,6 +404,28 @@ func GetHcnACLPolicy(policy Policy) (hcn.EndpointPolicy, error) {
386404
return aclEndpolicySetting, nil
387405
}
388406

407+
// GetHcnL4WFPProxyPolicy returns L4WFPProxy policy.
408+
func GetHcnL4WFPProxyPolicy(policy Policy) (hcn.EndpointPolicy, error) {
409+
l4WfpEndpolicySetting := hcn.EndpointPolicy{
410+
Type: hcn.L4WFPPROXY,
411+
}
412+
413+
// Check beforehand, the input meets the expected format
414+
// otherwise, endpoint creation will fail later on.
415+
var l4WfpProxyPolicySetting hcn.L4WfpProxyPolicySetting
416+
if err := json.Unmarshal(policy.Data, &l4WfpProxyPolicySetting); err != nil {
417+
return l4WfpEndpolicySetting, err
418+
}
419+
420+
l4WfpProxyPolicySettingBytes, err := json.Marshal(l4WfpProxyPolicySetting)
421+
if err != nil {
422+
return l4WfpEndpolicySetting, err
423+
}
424+
425+
l4WfpEndpolicySetting.Settings = l4WfpProxyPolicySettingBytes
426+
return l4WfpEndpolicySetting, nil
427+
}
428+
389429
// GetHcnEndpointPolicies returns array of all endpoint policies.
390430
func GetHcnEndpointPolicies(policyType CNIPolicyType, policies []Policy, epInfoData map[string]interface{}, enableSnatForDns, enableMultiTenancy bool) ([]hcn.EndpointPolicy, error) {
391431
var (
@@ -408,6 +448,8 @@ func GetHcnEndpointPolicies(policyType CNIPolicyType, policies []Policy, epInfoD
408448
endpointPolicy, err = GetHcnPortMappingPolicy(policy)
409449
case ACLPolicy:
410450
endpointPolicy, err = GetHcnACLPolicy(policy)
451+
case L4WFPProxyPolicy:
452+
endpointPolicy, err = GetHcnL4WFPProxyPolicy(policy)
411453
default:
412454
// return error as we should be able to parse all the policies specified
413455
return hcnEndPointPolicies, fmt.Errorf("Failed to set Policy: Type: %s, Data: %s", policy.Type, policy.Data)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2021 Microsoft. All rights reserved.
2+
// MIT License
3+
4+
package policy
5+
6+
import (
7+
"testing"
8+
9+
. "github.com/onsi/ginkgo"
10+
. "github.com/onsi/gomega"
11+
)
12+
13+
func TestEndpoint(t *testing.T) {
14+
RegisterFailHandler(Fail)
15+
RunSpecs(t, "Endpoint Suite")
16+
}
17+
18+
var _ = Describe("Windows Policies", func() {
19+
Describe("Test GetHcnL4WFPProxyPolicy", func() {
20+
It("Should raise error for invalid json", func() {
21+
policy := Policy{
22+
Type: L4WFPProxyPolicy,
23+
Data: []byte(`invalid json`),
24+
}
25+
26+
_, err := GetHcnL4WFPProxyPolicy(policy)
27+
Expect(err).NotTo(BeNil())
28+
})
29+
30+
It("Should marshall the policy correctly", func() {
31+
policy := Policy{
32+
Type: L4WFPProxyPolicy,
33+
Data: []byte(`{
34+
"Type": "L4WFPPROXY",
35+
"OutboundProxyPort": "15001",
36+
"InboundProxyPort": "15003",
37+
"UserSID": "S-1-5-32-556",
38+
"FilterTuple": {
39+
"Protocols": "6"
40+
}}`),
41+
}
42+
43+
expected_policy := `{"InboundProxyPort":"15003","OutboundProxyPort":"15001","FilterTuple":{"Protocols":"6"},"UserSID":"S-1-5-32-556","InboundExceptions":{},"OutboundExceptions":{}}`
44+
45+
generatedPolicy, err := GetHcnL4WFPProxyPolicy(policy)
46+
Expect(err).To(BeNil())
47+
Expect(string(generatedPolicy.Settings)).To(Equal(expected_policy))
48+
})
49+
})
50+
})

0 commit comments

Comments
 (0)