containernetworking-plugins/pkg/hns/netconf_windows.go
Nathan Gieseker 57b42a7b99 Windows: Adds HCS Calls and Bug Fixes
Move the windows plugin to use the Host Compute (v2) APIs, as well
as clean-up the code. Allows win-bridge to use either the old API or Host Compute (v2) api
depending on a conf parameter. Fixes a leaked endpoint issue on windows for the v1 flow, and
removes the hns/pkg from the linux test run.
2019-02-27 08:49:34 -08:00

153 lines
4.0 KiB
Go

// Copyright 2017 CNI authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hns
import (
"bytes"
"encoding/json"
"github.com/Microsoft/hcsshim/hcn"
"github.com/buger/jsonparser"
"github.com/containernetworking/cni/pkg/types"
"strings"
)
// NetConf is the CNI spec
type NetConf struct {
types.NetConf
HcnPolicyArgs []hcn.EndpointPolicy `json:"HcnPolicyArgs,omitempty"`
Policies []policy `json:"policies,omitempty"`
}
type policy struct {
Name string `json:"name"`
Value json.RawMessage `json:"value"`
}
// MarshalPolicies converts the Endpoint policies in Policies
// to HNS specific policies as Json raw bytes
func (n *NetConf) MarshalPolicies() []json.RawMessage {
if n.Policies == nil {
n.Policies = make([]policy, 0)
}
result := make([]json.RawMessage, 0, len(n.Policies))
for _, p := range n.Policies {
if !strings.EqualFold(p.Name, "EndpointPolicy") {
continue
}
result = append(result, p.Value)
}
return result
}
// ApplyOutboundNatPolicy applies NAT Policy in VFP using HNS
// Simultaneously an exception is added for the network that has to be Nat'd
func (n *NetConf) ApplyOutboundNatPolicy(nwToNat string) {
if n.Policies == nil {
n.Policies = make([]policy, 0)
}
nwToNatBytes := []byte(nwToNat)
for i, p := range n.Policies {
if !strings.EqualFold(p.Name, "EndpointPolicy") {
continue
}
typeValue, err := jsonparser.GetUnsafeString(p.Value, "Type")
if err != nil || len(typeValue) == 0 {
continue
}
if !strings.EqualFold(typeValue, "OutBoundNAT") {
continue
}
exceptionListValue, dt, _, _ := jsonparser.Get(p.Value, "ExceptionList")
// OutBoundNAT must with ExceptionList, so don't need to judge jsonparser.NotExist
if dt == jsonparser.Array {
buf := bytes.Buffer{}
buf.WriteString(`{"Type": "OutBoundNAT", "ExceptionList": [`)
jsonparser.ArrayEach(exceptionListValue, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
if dataType == jsonparser.String && len(value) != 0 {
if bytes.Compare(value, nwToNatBytes) != 0 {
buf.WriteByte('"')
buf.Write(value)
buf.WriteByte('"')
buf.WriteByte(',')
}
}
})
buf.WriteString(`"` + nwToNat + `"]}`)
n.Policies[i] = policy{
Name: "EndpointPolicy",
Value: buf.Bytes(),
}
} else {
n.Policies[i] = policy{
Name: "EndpointPolicy",
Value: []byte(`{"Type": "OutBoundNAT", "ExceptionList": ["` + nwToNat + `"]}`),
}
}
return
}
// didn't find the policyArg, add it
n.Policies = append(n.Policies, policy{
Name: "EndpointPolicy",
Value: []byte(`{"Type": "OutBoundNAT", "ExceptionList": ["` + nwToNat + `"]}`),
})
}
// ApplyDefaultPAPolicy is used to configure a endpoint PA policy in HNS
func (n *NetConf) ApplyDefaultPAPolicy(paAddress string) {
if n.Policies == nil {
n.Policies = make([]policy, 0)
}
// if its already present, leave untouched
for i, p := range n.Policies {
if !strings.EqualFold(p.Name, "EndpointPolicy") {
continue
}
paValue, dt, _, _ := jsonparser.Get(p.Value, "PA")
if dt == jsonparser.NotExist {
continue
} else if dt == jsonparser.String && len(paValue) != 0 {
// found it, don't override
return
}
n.Policies[i] = policy{
Name: "EndpointPolicy",
Value: []byte(`{"Type": "PA", "PA": "` + paAddress + `"}`),
}
return
}
// didn't find the policyArg, add it
n.Policies = append(n.Policies, policy{
Name: "EndpointPolicy",
Value: []byte(`{"Type": "PA", "PA": "` + paAddress + `"}`),
})
}