diff --git a/cni/azure-windows-multitenancy.conflist b/cni/azure-windows-multitenancy.conflist index c3218f3b71..f3a1c09b63 100644 --- a/cni/azure-windows-multitenancy.conflist +++ b/cni/azure-windows-multitenancy.conflist @@ -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 + } + } + ] + } + ] } \ No newline at end of file diff --git a/network/endpoint_windows.go b/network/endpoint_windows.go index f9527944ee..742d338c21 100644 --- a/network/endpoint_windows.go +++ b/network/endpoint_windows.go @@ -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. diff --git a/network/network_windows.go b/network/network_windows.go index b3ecd5e5dd..21258111dd 100644 --- a/network/network_windows.go +++ b/network/network_windows.go @@ -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 diff --git a/network/policy/policy.go b/network/policy/policy.go index 355aae6663..730cd0e171 100644 --- a/network/policy/policy.go +++ b/network/policy/policy.go @@ -2,7 +2,6 @@ package policy import ( "encoding/json" - "log" ) const ( @@ -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 -} diff --git a/network/policy/policy_windows.go b/network/policy/policy_windows.go new file mode 100644 index 0000000000..763fe9caa7 --- /dev/null +++ b/network/policy/policy_windows.go @@ -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") +}