Skip to content

Commit

Permalink
Fix Endpoint policy regression (#268)
Browse files Browse the repository at this point in the history
Fix endpoint policy regression
  • Loading branch information
ashvindeodhar authored and Yongli Chen committed Nov 20, 2018
1 parent bfb3eaa commit 3f1216e
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 92 deletions.
67 changes: 46 additions & 21 deletions cni/azure-windows-multitenancy.conflist
Original file line number Diff line number Diff line change
@@ -1,23 +1,48 @@
{
"cniVersion":"0.3.0",
"name":"azure",
"plugins":[
{
"type":"azure-vnet",
"mode":"bridge",
"bridge":"azure0",
"multiTenancy":true,
"enableSnatOnHost":true,
"ipam":{
"type":"azure-vnet-ipam"
}
},
{
"type":"portmap",
"capabilities":{
"portMappings":true
},
"snat":true
}
]
"cniVersion": "0.3.0",
"name": "azure",
"plugins": [
{
"type": "azure-vnet",
"mode": "bridge",
"bridge": "azure0",
"multiTenancy":true,
"enableSnatOnHost":true,
"capabilities": {
"portMappings": true
},
"ipam": {
"type": "azure-vnet-ipam"
},
"dns": {
"Nameservers": [
"10.0.0.10",
"168.63.129.16"
],
"Search": [
"svc.cluster.local"
]
},
"AdditionalArgs": [
{
"Name": "EndpointPolicy",
"Value": {
"Type": "OutBoundNAT",
"ExceptionList": [
"10.240.0.0/16",
"10.0.0.0/8"
]
}
},
{
"Name": "EndpointPolicy",
"Value": {
"Type": "ROUTE",
"DestinationPrefix": "10.0.0.0/8",
"NeedEncap": true
}
}
]
}
]
}
30 changes: 1 addition & 29 deletions network/endpoint_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,7 @@ func (nw *network) newEndpointImpl(epInfo *EndpointInfo) (*endpoint, error) {
VirtualNetwork: nw.HnsId,
DNSSuffix: epInfo.DNS.Suffix,
DNSServerList: strings.Join(epInfo.DNS.Servers, ","),
}

// Set outbound NAT policy
outBoundNatPolicy := hcsshim.OutboundNatPolicy{}
outBoundNatPolicy.Policy.Type = hcsshim.OutboundNat

exceptionList, err := policy.GetOutBoundNatExceptionList(epInfo.Policies)
if err != nil {
log.Printf("[net] Failed to parse outbound NAT policy %v", err)
return nil, err
}

if exceptionList != nil {
for _, ipAddress := range exceptionList {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}

if epInfo.Data[CnetAddressSpace] != nil {
if cnetAddressSpace := epInfo.Data[CnetAddressSpace].([]string); cnetAddressSpace != nil {
for _, ipAddress := range cnetAddressSpace {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}
}

if outBoundNatPolicy.Exceptions != nil {
serializedOutboundNatPolicy, _ := json.Marshal(outBoundNatPolicy)
hnsEndpoint.Policies = append(hnsEndpoint.Policies, serializedOutboundNatPolicy)
Policies: policy.SerializePolicies(policy.EndpointPolicy, epInfo.Policies, epInfo.Data),
}

// HNS currently supports only one IP address per endpoint.
Expand Down
2 changes: 1 addition & 1 deletion network/network_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (nm *networkManager) newNetworkImpl(nwInfo *NetworkInfo, extIf *externalInt
Name: nwInfo.Id,
NetworkAdapterName: networkAdapterName,
DNSServerList: strings.Join(nwInfo.DNS.Servers, ","),
Policies: policy.SerializePolicies(policy.NetworkPolicy, nwInfo.Policies),
Policies: policy.SerializePolicies(policy.NetworkPolicy, nwInfo.Policies, nil),
}

// Set the VLAN and OutboundNAT policies
Expand Down
41 changes: 0 additions & 41 deletions network/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package policy

import (
"encoding/json"
"log"
)

const (
Expand All @@ -17,43 +16,3 @@ type Policy struct {
Type CNIPolicyType
Data json.RawMessage
}

// SerializePolicies serializes policies to json.
func SerializePolicies(policyType CNIPolicyType, policies []Policy) []json.RawMessage {
var jsonPolicies []json.RawMessage
for _, policy := range policies {
if policy.Type == policyType {
jsonPolicies = append(jsonPolicies, policy.Data)
}
}
return jsonPolicies
}

// GetOutBoundNatExceptionList returns exception list for outbound nat policy
func GetOutBoundNatExceptionList(policies []Policy) ([]string, error) {
type KVPair struct {
Type CNIPolicyType `json:"Type"`
ExceptionList json.RawMessage `json:"ExceptionList"`
}

for _, policy := range policies {
if policy.Type == EndpointPolicy {
var data KVPair
if err := json.Unmarshal(policy.Data, &data); err != nil {
return nil, err
}

if data.Type == OutBoundNatPolicy {
var exceptionList []string
if err := json.Unmarshal(data.ExceptionList, &exceptionList); err != nil {
return nil, err
}

return exceptionList, nil
}
}
}

log.Printf("OutBoundNAT policy not set.")
return nil, nil
}
110 changes: 110 additions & 0 deletions network/policy/policy_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package policy

import (
"encoding/json"
"fmt"
"log"

"github.com/Microsoft/hcsshim"
)

// SerializePolicies serializes policies to json.
func SerializePolicies(policyType CNIPolicyType, policies []Policy, epInfoData map[string]interface{}) []json.RawMessage {
var jsonPolicies []json.RawMessage
for _, policy := range policies {
if policy.Type == policyType {
if isPolicyTypeOutBoundNAT := IsPolicyTypeOutBoundNAT(policy); isPolicyTypeOutBoundNAT {
if serializedOutboundNatPolicy, err := SerializeOutBoundNATPolicy(policies, epInfoData); err != nil {
log.Printf("Failed to serialize OutBoundNAT policy")
} else {
jsonPolicies = append(jsonPolicies, serializedOutboundNatPolicy)
}
} else {
jsonPolicies = append(jsonPolicies, policy.Data)
}
}
}
return jsonPolicies
}

// GetOutBoundNatExceptionList returns exception list for outbound nat policy
func GetOutBoundNatExceptionList(policies []Policy) ([]string, error) {
type KVPair struct {
Type CNIPolicyType `json:"Type"`
ExceptionList json.RawMessage `json:"ExceptionList"`
}

for _, policy := range policies {
if policy.Type == EndpointPolicy {
var data KVPair
if err := json.Unmarshal(policy.Data, &data); err != nil {
return nil, err
}

if data.Type == OutBoundNatPolicy {
var exceptionList []string
if err := json.Unmarshal(data.ExceptionList, &exceptionList); err != nil {
return nil, err
}

return exceptionList, nil
}
}
}

log.Printf("OutBoundNAT policy not set")
return nil, nil
}

// IsPolicyTypeOutBoundNAT return true if the policy type is OutBoundNAT
func IsPolicyTypeOutBoundNAT(policy Policy) bool {
if policy.Type == EndpointPolicy {
type KVPair struct {
Type CNIPolicyType `json:"Type"`
ExceptionList json.RawMessage `json:"ExceptionList"`
}
var data KVPair
if err := json.Unmarshal(policy.Data, &data); err != nil {
return false
}

if data.Type == OutBoundNatPolicy {
return true
}
}

return false
}

// SerializeOutBoundNATPolicy formulates OutBoundNAT policy and returns serialized json
func SerializeOutBoundNATPolicy(policies []Policy, epInfoData map[string]interface{}) (json.RawMessage, error) {
outBoundNatPolicy := hcsshim.OutboundNatPolicy{}
outBoundNatPolicy.Policy.Type = hcsshim.OutboundNat

exceptionList, err := GetOutBoundNatExceptionList(policies)
if err != nil {
log.Printf("Failed to parse outbound NAT policy %v", err)
return nil, err
}

if exceptionList != nil {
for _, ipAddress := range exceptionList {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}

if epInfoData["cnetAddressSpace"] != nil {
if cnetAddressSpace := epInfoData["cnetAddressSpace"].([]string); cnetAddressSpace != nil {
for _, ipAddress := range cnetAddressSpace {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}
}

if outBoundNatPolicy.Exceptions != nil {
serializedOutboundNatPolicy, _ := json.Marshal(outBoundNatPolicy)
return serializedOutboundNatPolicy, nil
}

return nil, fmt.Errorf("OutBoundNAT policy not set")
}

0 comments on commit 3f1216e

Please sign in to comment.