mirror of
https://github.com/k8snetworkplumbingwg/multus-cni.git
synced 2025-08-31 08:33:06 +00:00
rebase the #165 PR commit
This commit is contained in:
108
multus/multus.go
108
multus/multus.go
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
cnitypes "github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
cniversion "github.com/containernetworking/cni/pkg/version"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
k8s "github.com/intel/multus-cni/k8sclient"
|
||||
@@ -281,6 +282,105 @@ func delPlugins(exec invoke.Exec, argIfname string, delegates []*types.DelegateN
|
||||
return nil
|
||||
}
|
||||
|
||||
func mergeWithResult(srcObj, dstObj cnitypes.Result) (cnitypes.Result, error) {
|
||||
srcObj, err := updateRoutes(srcObj)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Routes update failed: %v", err)
|
||||
}
|
||||
|
||||
srcObj, err = fixInterfaces(srcObj)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Failed to fix interfaces: %v", err)
|
||||
}
|
||||
|
||||
if dstObj == nil {
|
||||
return srcObj, nil
|
||||
}
|
||||
src, err := current.NewResultFromResult(srcObj)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Couldn't convert old result to current version: %v", err)
|
||||
}
|
||||
dst, err := current.NewResultFromResult(dstObj)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Couldn't convert old result to current version: %v", err)
|
||||
}
|
||||
|
||||
ifacesLength := len(dst.Interfaces)
|
||||
|
||||
for _, iface := range src.Interfaces {
|
||||
dst.Interfaces = append(dst.Interfaces, iface)
|
||||
}
|
||||
for _, ip := range src.IPs {
|
||||
if ip.Interface != nil && *(ip.Interface) != -1 {
|
||||
ip.Interface = current.Int(*(ip.Interface) + ifacesLength)
|
||||
}
|
||||
dst.IPs = append(dst.IPs, ip)
|
||||
}
|
||||
for _, route := range src.Routes {
|
||||
dst.Routes = append(dst.Routes, route)
|
||||
}
|
||||
|
||||
for _, ns := range src.DNS.Nameservers {
|
||||
dst.DNS.Nameservers = append(dst.DNS.Nameservers, ns)
|
||||
}
|
||||
for _, s := range src.DNS.Search {
|
||||
dst.DNS.Search = append(dst.DNS.Search, s)
|
||||
}
|
||||
for _, opt := range src.DNS.Options {
|
||||
dst.DNS.Options = append(dst.DNS.Options, opt)
|
||||
}
|
||||
// TODO: what about DNS.domain?
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// updateRoutes changes nil gateway set in a route to a gateway from IPConfig
|
||||
// nil gw in route means default gw from result. When merging results from
|
||||
// many results default gw may be set from another CNI network. This may lead to
|
||||
// wrong routes.
|
||||
func updateRoutes(rObj cnitypes.Result) (cnitypes.Result, error) {
|
||||
result, err := current.NewResultFromResult(rObj)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Couldn't convert old result to current version: %v", err)
|
||||
}
|
||||
if len(result.Routes) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var gw net.IP
|
||||
for _, ip := range result.IPs {
|
||||
if ip.Gateway != nil {
|
||||
gw = ip.Gateway
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, route := range result.Routes {
|
||||
if route.GW == nil {
|
||||
if gw == nil {
|
||||
return nil, logging.Errorf("Couldn't find gw in result %v", result)
|
||||
}
|
||||
route.GW = gw
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// fixInterfaces fixes bad result returned by CNI plugin
|
||||
// some plugins(for example calico) return empty Interfaces list but
|
||||
// in IPConfig sets Interface index to 0. In such case it should be nil
|
||||
func fixInterfaces(rObj cnitypes.Result) (cnitypes.Result, error) {
|
||||
result, err := current.NewResultFromResult(rObj)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Couldn't convert old result to current version: %v", err)
|
||||
}
|
||||
if len(result.Interfaces) == 0 {
|
||||
for _, ip := range result.IPs {
|
||||
ip.Interface = nil
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cnitypes.Result, error) {
|
||||
logging.Debugf("cmdAdd: %v, %v, %v", args, exec, kubeClient)
|
||||
n, err := types.LoadNetConf(args.StdinData)
|
||||
@@ -337,10 +437,10 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cn
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
// Master plugin result is always used if present
|
||||
if delegate.MasterPlugin || result == nil {
|
||||
result = tmpResult
|
||||
// Merge results from delegates
|
||||
result, err = mergeWithResult(tmpResult, result)
|
||||
if err != nil {
|
||||
return nil, logging.Errorf("Multus: Failed to merge results: %v", err)
|
||||
}
|
||||
|
||||
//create the network status, only in case Multus as kubeconfig
|
||||
|
Reference in New Issue
Block a user