V2 API support for win-overlay CNI
This PR bring V2 API support into win-overlay CNI. With the current V1 API, only docker runtime works for win-overlay. By bringing new changes, we should be able to use containerd as the runtime.Below are the key points regarding this implementation. 1. Clear seperation for V1 & V2 API support 2. New cni.conf sample that works for win-overlay Signed-off-by: selansen <esiva@redhat.com> Signed-off-by: mansikulkarni96 <mankulka@redhat.com>
This commit is contained in:
parent
16e4a82b32
commit
8b8825bcd8
@ -39,6 +39,7 @@ type EndpointInfo struct {
|
||||
NetworkId string
|
||||
Gateway net.IP
|
||||
IpAddress net.IP
|
||||
MacAddress string
|
||||
}
|
||||
|
||||
// GetSandboxContainerID returns the sandbox ID of this pod.
|
||||
@ -248,6 +249,7 @@ func GenerateHcnEndpoint(epInfo *EndpointInfo, n *NetConf) (*hcn.HostComputeEndp
|
||||
Minor: 0,
|
||||
},
|
||||
Name: epInfo.EndpointName,
|
||||
MacAddress: epInfo.MacAddress,
|
||||
HostComputeNetwork: epInfo.NetworkId,
|
||||
Dns: hcn.Dns{
|
||||
Domain: epInfo.DNS.Domain,
|
||||
@ -280,6 +282,16 @@ func RemoveHcnEndpoint(epName string) error {
|
||||
}
|
||||
return errors.Annotatef(err, "failed to find HostComputeEndpoint %s", epName)
|
||||
}
|
||||
epNamespace, err := hcn.GetNamespaceByID(hcnEndpoint.HostComputeNamespace)
|
||||
if err != nil && !hcn.IsNotFoundError(err) {
|
||||
return errors.Annotatef(err, "failed to get HostComputeNamespace %s", epName)
|
||||
}
|
||||
if epNamespace != nil {
|
||||
err = hcn.RemoveNamespaceEndpoint(hcnEndpoint.HostComputeNamespace, hcnEndpoint.Id)
|
||||
if err != nil && !hcn.IsNotFoundError(err) {
|
||||
return errors.Annotatef(err,"error removing endpoint: %s from namespace", epName)
|
||||
}
|
||||
}
|
||||
|
||||
err = hcnEndpoint.Delete()
|
||||
if err != nil {
|
||||
|
46
plugins/main/windows/win-overlay/sample-v2.conf
Normal file
46
plugins/main/windows/win-overlay/sample-v2.conf
Normal file
@ -0,0 +1,46 @@
|
||||
{
|
||||
"cniVersion": "0.2.0",
|
||||
"name": "OVNKubernetesHybridOverlayNetwork",
|
||||
"type": "win-overlay",
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.132.0.0/24"
|
||||
},
|
||||
"apiVersion": 2,
|
||||
"capabilities": {
|
||||
"portMappings": true,
|
||||
"dns": true
|
||||
},
|
||||
"policies": [
|
||||
{
|
||||
"name": "EndpointPolicy",
|
||||
"value": {
|
||||
"Type": "OutBoundNAT",
|
||||
"Settings": {
|
||||
"Exceptions": [
|
||||
"172.30.0.0/16"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "EndpointPolicy",
|
||||
"value": {
|
||||
"Type": "SDNRoute",
|
||||
"Settings": {
|
||||
"DestinationPrefix": "172.30.0.0/16",
|
||||
"NeedEncap": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "EndpointPolicy",
|
||||
"value": {
|
||||
"Type": "ProviderAddress",
|
||||
"Settings": {
|
||||
"ProviderAddress": "10.0.133.170"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -17,11 +17,13 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
|
||||
"github.com/Microsoft/hcsshim/hcn"
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
@ -55,16 +57,106 @@ func loadNetConf(bytes []byte) (*NetConf, string, error) {
|
||||
return n, n.CNIVersion, nil
|
||||
}
|
||||
|
||||
func cmdAdd(args *skel.CmdArgs) error {
|
||||
success := false
|
||||
n, cniVersion, err := loadNetConf(args.StdinData)
|
||||
if err != nil {
|
||||
return errors.Annotate(err, "error while loadNetConf")
|
||||
func processEndpointArgs(args *skel.CmdArgs, n *NetConf) (*hns.EndpointInfo, error) {
|
||||
epInfo := new(hns.EndpointInfo)
|
||||
epInfo.NetworkName = n.Name
|
||||
epInfo.EndpointName = hns.ConstructEndpointName(args.ContainerID, args.Netns, epInfo.NetworkName)
|
||||
|
||||
if n.IPAM.Type != "" {
|
||||
r, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "error while executing IPAM addition")
|
||||
}
|
||||
|
||||
// convert whatever the IPAM result was into the current result
|
||||
result, err := current.NewResultFromResult(r)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "error while converting the result from IPAM addition")
|
||||
}
|
||||
if len(result.IPs) == 0 {
|
||||
return nil, fmt.Errorf("IPAM plugin return is missing IP config")
|
||||
}
|
||||
epInfo.IpAddress = result.IPs[0].Address.IP.To4()
|
||||
if epInfo.IpAddress == nil {
|
||||
return nil, fmt.Errorf("IPAM plugin return is missing valid IP Address")
|
||||
}
|
||||
epInfo.MacAddress = fmt.Sprintf("%v-%02x-%02x-%02x-%02x", n.EndpointMacPrefix, epInfo.IpAddress[0], epInfo.IpAddress[1], epInfo.IpAddress[2], epInfo.IpAddress[3])
|
||||
|
||||
}
|
||||
epInfo.DNS = n.GetDNS()
|
||||
if n.LoopbackDSR {
|
||||
n.ApplyLoopbackDSRPolicy(&epInfo.IpAddress)
|
||||
}
|
||||
return epInfo, nil
|
||||
}
|
||||
|
||||
func cmdHcnAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
|
||||
if len(n.EndpointMacPrefix) != 0 {
|
||||
if len(n.EndpointMacPrefix) != 5 || n.EndpointMacPrefix[2] != '-' {
|
||||
return nil, fmt.Errorf("endpointMacPrefix [%v] is invalid, value must be of the format xx-xx", n.EndpointMacPrefix)
|
||||
}
|
||||
} else {
|
||||
n.EndpointMacPrefix = "0E-2A"
|
||||
}
|
||||
|
||||
networkName := n.Name
|
||||
hnsNetwork, err := hcsshim.GetHNSNetworkByName(networkName)
|
||||
hcnNetwork, err := hcn.GetNetworkByName(networkName)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "error while hcn.GetNetworkByName(%s)", networkName)
|
||||
}
|
||||
if hcnNetwork == nil {
|
||||
return nil, fmt.Errorf("network %v is not found", networkName)
|
||||
}
|
||||
if hnsNetwork == nil {
|
||||
return nil, fmt.Errorf("network %v not found", networkName)
|
||||
}
|
||||
|
||||
if !strings.EqualFold(string (hcnNetwork.Type), "Overlay") {
|
||||
return nil, fmt.Errorf("network %v is of an unexpected type: %v", networkName, hcnNetwork.Type)
|
||||
}
|
||||
|
||||
epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)
|
||||
|
||||
hcnEndpoint, err := hns.AddHcnEndpoint(epName, hcnNetwork.Id, args.Netns, func() (*hcn.HostComputeEndpoint, error) {
|
||||
epInfo, err := processEndpointArgs(args, n)
|
||||
if err != nil {
|
||||
return nil, errors.Annotate(err, "error while processing endpoint args")
|
||||
}
|
||||
epInfo.NetworkId = hcnNetwork.Id
|
||||
gatewayAddr := net.ParseIP(hnsNetwork.Subnets[0].GatewayAddress)
|
||||
epInfo.Gateway = gatewayAddr.To4()
|
||||
n.ApplyDefaultPAPolicy(hnsNetwork.ManagementIP)
|
||||
if n.IPMasq {
|
||||
n.ApplyOutboundNatPolicy(hnsNetwork.Subnets[0].AddressPrefix)
|
||||
}
|
||||
hcnEndpoint, err := hns.GenerateHcnEndpoint(epInfo, &n.NetConf)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Annotate(err, "error while generating HostComputeEndpoint")
|
||||
}
|
||||
return hcnEndpoint, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Annotate(err, "error while adding HostComputeEndpoint")
|
||||
}
|
||||
|
||||
result, err := hns.ConstructHcnResult(hcnNetwork, hcnEndpoint)
|
||||
|
||||
if err != nil {
|
||||
ipam.ExecDel(n.IPAM.Type, args.StdinData)
|
||||
return nil, errors.Annotate(err, "error while constructing HostComputeEndpoint addition result")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
func cmdHnsAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
|
||||
success := false
|
||||
|
||||
if len(n.EndpointMacPrefix) != 0 {
|
||||
if len(n.EndpointMacPrefix) != 5 || n.EndpointMacPrefix[2] != '-' {
|
||||
return fmt.Errorf("endpointMacPrefix [%v] is invalid, value must be of the format xx-xx", n.EndpointMacPrefix)
|
||||
return nil, fmt.Errorf("endpointMacPrefix [%v] is invalid, value must be of the format xx-xx", n.EndpointMacPrefix)
|
||||
}
|
||||
} else {
|
||||
n.EndpointMacPrefix = "0E-2A"
|
||||
@ -73,15 +165,15 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
networkName := n.Name
|
||||
hnsNetwork, err := hcsshim.GetHNSNetworkByName(networkName)
|
||||
if err != nil {
|
||||
return errors.Annotatef(err, "error while GETHNSNewtorkByName(%s)", networkName)
|
||||
return nil, errors.Annotatef(err, "error while GETHNSNewtorkByName(%s)", networkName)
|
||||
}
|
||||
|
||||
if hnsNetwork == nil {
|
||||
return fmt.Errorf("network %v not found", networkName)
|
||||
return nil, fmt.Errorf("network %v not found", networkName)
|
||||
}
|
||||
|
||||
if !strings.EqualFold(hnsNetwork.Type, "Overlay") {
|
||||
return fmt.Errorf("network %v is of an unexpected type: %v", networkName, hnsNetwork.Type)
|
||||
return nil, fmt.Errorf("network %v is of an unexpected type: %v", networkName, hnsNetwork.Type)
|
||||
}
|
||||
|
||||
epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)
|
||||
@ -140,15 +232,34 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
return errors.Annotatef(err, "error while AddHnsEndpoint(%v,%v,%v)", epName, hnsNetwork.Id, args.ContainerID)
|
||||
return nil, errors.Annotatef(err, "error while AddHnsEndpoint(%v,%v,%v)", epName, hnsNetwork.Id, args.ContainerID)
|
||||
}
|
||||
|
||||
result, err := hns.ConstructHnsResult(hnsNetwork, hnsEndpoint)
|
||||
if err != nil {
|
||||
return errors.Annotatef(err, "error while constructResult")
|
||||
return nil, errors.Annotatef(err, "error while constructResult")
|
||||
}
|
||||
|
||||
success = true
|
||||
return result, nil
|
||||
}
|
||||
func cmdAdd(args *skel.CmdArgs) error {
|
||||
n, cniVersion, err := loadNetConf(args.StdinData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var result *current.Result
|
||||
if n.ApiVersion == 2 {
|
||||
result, err = cmdHcnAdd(args, n)
|
||||
} else {
|
||||
result, err = cmdHnsAdd(args, n)
|
||||
}
|
||||
if err != nil {
|
||||
ipam.ExecDel(n.IPAM.Type, args.StdinData)
|
||||
return err
|
||||
}
|
||||
|
||||
return types.PrintResult(result, cniVersion)
|
||||
}
|
||||
|
||||
@ -158,12 +269,16 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ipam.ExecDel(n.IPAM.Type, args.StdinData); err != nil {
|
||||
return err
|
||||
if n.IPAM.Type != "" {
|
||||
if err := ipam.ExecDel(n.IPAM.Type, args.StdinData); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)
|
||||
|
||||
if n.ApiVersion == 2 {
|
||||
return hns.RemoveHcnEndpoint(epName)
|
||||
}
|
||||
return hns.RemoveHnsEndpoint(epName, args.Netns, args.ContainerID)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user