Merge pull request #577 from Billy99/billy99-device-info

Add DeviceInfo Data to NetworkStatus Annotation
This commit is contained in:
Doug Smith
2020-12-01 13:50:26 -05:00
committed by GitHub
14 changed files with 454 additions and 96 deletions

2
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.8.2
github.com/json-iterator/go v1.1.9 // indirect
github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d
github.com/onsi/ginkgo v1.11.0
github.com/onsi/gomega v1.7.0
github.com/pkg/errors v0.8.1

8
go.sum
View File

@@ -59,6 +59,7 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
@@ -119,8 +120,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/juju/errors v0.0.0-20180806074554-22422dad46e1/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc h1:M7bj0RX9dc79YIyptmHm0tPmC/WuIbn+HVeTBDK2KZw=
github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc/go.mod h1:+1DpV8uIwteAhxNO0lgRox8gHkTG6w3OeDfAlg+qqjA=
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d h1:9QbZltQGRFe7temwcTDjj8rIbow48Gv6mIKOxuks+OI=
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d/go.mod h1:+1DpV8uIwteAhxNO0lgRox8gHkTG6w3OeDfAlg+qqjA=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -134,6 +135,7 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -303,8 +305,10 @@ k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk=
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k=
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
k8s.io/code-generator v0.18.3 h1:5H57pYEbkMMXCLKD16YQH3yDPAbVLweUsB1M3m70D1c=
k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120 h1:RPscN6KhmG54S33L+lr3GS+oD1jmchIU0ll519K6FA4=
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=

View File

@@ -285,7 +285,7 @@ func getKubernetesDelegate(client *ClientInfo, net *types.NetworkSelectionElemen
return nil, resourceMap, err
}
delegate, err := types.LoadDelegateNetConf(configBytes, net, deviceID)
delegate, err := types.LoadDelegateNetConf(configBytes, net, deviceID, resourceName)
if err != nil {
return nil, resourceMap, err
}
@@ -495,7 +495,7 @@ func getNetDelegate(client *ClientInfo, pod *v1.Pod, netname, confdir, namespace
var configBytes []byte
configBytes, err = netutils.GetCNIConfigFromFile(netname, confdir)
if err == nil {
delegate, err := types.LoadDelegateNetConf(configBytes, nil, "")
delegate, err := types.LoadDelegateNetConf(configBytes, nil, "", "")
if err != nil {
return nil, resourceMap, err
}
@@ -514,7 +514,7 @@ func getNetDelegate(client *ClientInfo, pod *v1.Pod, netname, confdir, namespace
var configBytes []byte
configBytes, err = netutils.GetCNIConfigFromFile("", netname)
if err == nil {
delegate, err := types.LoadDelegateNetConf(configBytes, nil, "")
delegate, err := types.LoadDelegateNetConf(configBytes, nil, "", "")
if err != nil {
return nil, resourceMap, err
}

View File

@@ -1184,10 +1184,10 @@ users:
}
}`
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "")
Expect(err).NotTo(HaveOccurred())
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
Expect(err).NotTo(HaveOccurred())
@@ -1266,10 +1266,10 @@ users:
}
}`
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "")
Expect(err).NotTo(HaveOccurred())
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
Expect(err).NotTo(HaveOccurred())
@@ -1326,10 +1326,10 @@ users:
}`
// note that the provided kubeconfig is invalid
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "")
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "", "")
Expect(err).NotTo(HaveOccurred())
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
Expect(err).NotTo(HaveOccurred())
@@ -1385,10 +1385,10 @@ users:
}
}`
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "")
Expect(err).NotTo(HaveOccurred())
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
Expect(err).NotTo(HaveOccurred())

View File

@@ -104,6 +104,20 @@ func getIfname(delegate *types.DelegateNetConf, argif string, idx int) string {
return fmt.Sprintf("net%d", idx)
}
func getDelegateDeviceInfo(delegate *types.DelegateNetConf, runtimeConf *libcni.RuntimeConf) (*nettypes.DeviceInfo, error) {
// If the DPDeviceInfoFile was created, it was copied to the CNIDeviceInfoFile.
// If the DPDeviceInfoFile was not created, CNI might have created it. So
// either way, load CNIDeviceInfoFile.
if info, ok := runtimeConf.CapabilityArgs["CNIDeviceInfoFile"]; ok {
if infostr, ok := info.(string); ok {
return nadutils.LoadDeviceInfoFromCNI(infostr)
}
} else {
logging.Debugf("getDelegateDeviceInfo(): No CapArgs - info=%v ok=%v", info, ok)
}
return nil, nil
}
func saveDelegates(containerID, dataDir string, delegates []*types.DelegateNetConf) error {
logging.Debugf("saveDelegates: %s, %s, %v", containerID, dataDir, delegates)
delegatesBytes, err := json.Marshal(delegates)
@@ -443,20 +457,31 @@ func delegateDel(exec invoke.Exec, pod *v1.Pod, ifName string, delegateConf *typ
return err
}
func delPlugins(exec invoke.Exec, pod *v1.Pod, argIfname string, delegates []*types.DelegateNetConf, lastIdx int, rt *libcni.RuntimeConf, binDir string) error {
logging.Debugf("delPlugins: %v, %v, %s, %v, %d, %v, %s", exec, pod, argIfname, delegates, lastIdx, rt, binDir)
// delPlugins deletes plugins in reverse order from lastdIdx
// Uses netRt as base RuntimeConf (coming from NetConf) but merges it
// with each of the delegates' configuration
func delPlugins(exec invoke.Exec, pod *v1.Pod, args *skel.CmdArgs, k8sArgs *types.K8sArgs, delegates []*types.DelegateNetConf, lastIdx int, netRt *types.RuntimeConfig, binDir string) error {
logging.Debugf("delPlugins: %v, %v, %v, %v, %v, %d, %v, %s", exec, pod, args, k8sArgs, delegates, lastIdx, netRt, binDir)
if os.Setenv("CNI_COMMAND", "DEL") != nil {
return logging.Errorf("delPlugins: error setting envionment variable CNI_COMMAND to a value of DEL")
return logging.Errorf("delPlugins: error setting environment variable CNI_COMMAND to a value of DEL")
}
var errorstrings []string
for idx := lastIdx; idx >= 0; idx-- {
ifName := getIfname(delegates[idx], argIfname, idx)
rt.IfName = ifName
ifName := getIfname(delegates[idx], args.IfName, idx)
rt, cniDeviceInfoPath := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, netRt, delegates[idx])
// Attempt to delete all but do not error out, instead, collect all errors.
if err := delegateDel(exec, pod, ifName, delegates[idx], rt, binDir); err != nil {
errorstrings = append(errorstrings, err.Error())
}
if cniDeviceInfoPath != "" {
err := nadutils.CleanDeviceInfoForCNI(cniDeviceInfoPath)
// Even if the filename is set, file may not be present. Ignore error,
// but log and in the future may need to filter on specific errors.
if err != nil {
logging.Debugf("delPlugins: CleanDeviceInfoForCNI returned an error - err=%v", err)
}
}
}
// Check if we had any errors, and send them all back.
@@ -562,9 +587,16 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c
cniArgs := os.Getenv("CNI_ARGS")
for idx, delegate := range n.Delegates {
ifName := getIfname(delegate, args.IfName, idx)
rt, cniDeviceInfoPath := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, n.RuntimeConfig, delegate)
if cniDeviceInfoPath != "" {
err = nadutils.CopyDeviceInfoForCNIFromDP(cniDeviceInfoPath, delegate.ResourceName, delegate.DeviceID)
// Even if the filename is set, file may not be present. Ignore error,
// but log and in the future may need to filter on specific errors.
if err != nil {
logging.Debugf("cmdAdd: CopyDeviceInfoForCNIFromDP returned an error - err=%v", err)
}
}
runtimeConfig := types.MergeCNIRuntimeConfig(n.RuntimeConfig, delegate)
rt := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, runtimeConfig)
tmpResult, err = delegateAdd(exec, kubeClient, pod, ifName, delegate, rt, n.BinDir, cniArgs)
if err != nil {
// If the add failed, tear down all networks we already added
@@ -573,7 +605,7 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c
netName = delegate.ConfList.Name
}
// Ignore errors; DEL must be idempotent anyway
_ = delPlugins(exec, nil, args.IfName, n.Delegates, idx, rt, n.BinDir)
_ = delPlugins(exec, nil, args, k8sArgs, n.Delegates, idx, n.RuntimeConfig, n.BinDir)
return nil, cmdPluginErr(k8sArgs, netName, "error adding container to network %q: %v", netName, err)
}
@@ -612,16 +644,28 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c
result = tmpResult
}
// Read devInfo from CNIDeviceInfoFile if it exists so
// it can be copied to the NetworkStatus.
devinfo, err := getDelegateDeviceInfo(delegate, rt)
if err != nil {
// Even if the filename is set, file may not be present. Ignore error,
// but log and in the future may need to filter on specific errors.
logging.Debugf("cmdAdd: getDelegateDeviceInfo returned an error - err=%v", err)
}
// create the network status, only in case Multus as kubeconfig
if n.Kubeconfig != "" && kc != nil {
if !types.CheckSystemNamespaces(string(k8sArgs.K8S_POD_NAME), n.SystemNamespaces) {
delegateNetStatus, err := nadutils.CreateNetworkStatus(tmpResult, delegate.Name, delegate.MasterPlugin)
delegateNetStatus, err := nadutils.CreateNetworkStatus(tmpResult, delegate.Name, delegate.MasterPlugin, devinfo)
if err != nil {
return nil, cmdErr(k8sArgs, "error setting network status: %v", err)
}
netStatus = append(netStatus, *delegateNetStatus)
}
} else if devinfo != nil {
// Warn that devinfo exists but could not add it to downwards API
logging.Errorf("devinfo available, but no kubeConfig so NetworkStatus not modified.")
}
}
@@ -656,8 +700,7 @@ func cmdCheck(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo)
for idx, delegate := range in.Delegates {
ifName := getIfname(delegate, args.IfName, idx)
runtimeConfig := types.MergeCNIRuntimeConfig(in.RuntimeConfig, delegate)
rt := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, runtimeConfig)
rt, _ := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, in.RuntimeConfig, delegate)
err = delegateCheck(exec, ifName, delegate, rt, in.BinDir)
if err != nil {
return err
@@ -808,8 +851,7 @@ func cmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) er
}
}
rt := types.CreateCNIRuntimeConf(args, k8sArgs, "", in.RuntimeConfig)
return delPlugins(exec, pod, args.IfName, in.Delegates, len(in.Delegates)-1, rt, in.BinDir)
return delPlugins(exec, pod, args, k8sArgs, in.Delegates, len(in.Delegates)-1, in.RuntimeConfig, in.BinDir)
}
func main() {

View File

@@ -2031,7 +2031,7 @@ var _ = Describe("multus operations cniVersion 0.2.0 config", func() {
rawnetconflist := []byte(`{"cniVersion":"0.2.0","name":"weave1","type":"weave-net"}`)
k8sargs, err := k8sclient.GetK8sArgs(args)
n, err := types.LoadNetConf(args.StdinData)
rt := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig)
rt, _ := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig, nil)
err = conflistDel(rt, rawnetconflist, binDir, fExec)
Expect(err).To(HaveOccurred())
@@ -3277,7 +3277,7 @@ var _ = Describe("multus operations cniVersion 0.4.0 config", func() {
rawnetconflist := []byte(`{"cniVersion":"0.4.0","name":"weave1","type":"weave-net"}`)
k8sargs, err := k8sclient.GetK8sArgs(args)
n, err := types.LoadNetConf(args.StdinData)
rt := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig)
rt, _ := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig, nil)
err = conflistDel(rt, rawnetconflist, binDir, fExec)
Expect(err).To(HaveOccurred())

View File

@@ -24,6 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/cni/pkg/version"
nadutils "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils"
"gopkg.in/intel/multus-cni.v3/logging"
)
@@ -55,7 +56,7 @@ func LoadDelegateNetConfList(bytes []byte, delegateConf *DelegateNetConf) error
}
// LoadDelegateNetConf converts raw CNI JSON into a DelegateNetConf structure
func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID string) (*DelegateNetConf, error) {
func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID string, resourceName string) (*DelegateNetConf, error) {
var err error
logging.Debugf("LoadDelegateNetConf: %s, %v, %s", string(bytes), net, deviceID)
@@ -87,6 +88,9 @@ func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID st
if err != nil {
return nil, logging.Errorf("LoadDelegateNetConf: failed to add deviceID in NetConf bytes: %v", err)
}
// Save them for housekeeping
delegateConf.ResourceName = resourceName
delegateConf.DeviceID = deviceID
}
if net != nil && net.CNIArgs != nil {
bytes, err = addCNIArgsInConfig(bytes, net.CNIArgs)
@@ -122,6 +126,13 @@ func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID st
if net.InfinibandGUIDRequest != "" {
delegateConf.InfinibandGUIDRequest = net.InfinibandGUIDRequest
}
if net.DeviceID != "" {
if deviceID != "" {
logging.Debugf("Warning: Both RuntimeConfig and ResourceMap provide deviceID. Ignoring RuntimeConfig")
} else {
delegateConf.DeviceID = net.DeviceID
}
}
}
delegateConf.Bytes = bytes
@@ -129,16 +140,16 @@ func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID st
return delegateConf, nil
}
// MergeCNIRuntimeConfig creates CNI runtimeconfig from delegate
func MergeCNIRuntimeConfig(runtimeConfig *RuntimeConfig, delegate *DelegateNetConf) *RuntimeConfig {
logging.Debugf("MergeCNIRuntimeConfig: %v %v", runtimeConfig, delegate)
// mergeCNIRuntimeConfig creates CNI runtimeconfig from delegate
func mergeCNIRuntimeConfig(runtimeConfig *RuntimeConfig, delegate *DelegateNetConf) *RuntimeConfig {
logging.Debugf("mergeCNIRuntimeConfig: %v %v", runtimeConfig, delegate)
if runtimeConfig == nil {
runtimeConfig = &RuntimeConfig{}
}
// multus inject RuntimeConfig only in case of non MasterPlugin.
if delegate.MasterPlugin != true {
logging.Debugf("MergeCNIRuntimeConfig: add runtimeConfig for net-attach-def: %v", runtimeConfig)
logging.Debugf("mergeCNIRuntimeConfig: add runtimeConfig for net-attach-def: %v", runtimeConfig)
if delegate.PortMappingsRequest != nil {
runtimeConfig.PortMaps = delegate.PortMappingsRequest
}
@@ -154,14 +165,31 @@ func MergeCNIRuntimeConfig(runtimeConfig *RuntimeConfig, delegate *DelegateNetCo
if delegate.InfinibandGUIDRequest != "" {
runtimeConfig.InfinibandGUID = delegate.InfinibandGUIDRequest
}
if delegate.DeviceID != "" {
runtimeConfig.DeviceID = delegate.DeviceID
}
logging.Debugf("mergeCNIRuntimeConfig: add runtimeConfig for net-attach-def: %v", runtimeConfig)
}
return runtimeConfig
}
// CreateCNIRuntimeConf create CNI RuntimeConf
func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, rc *RuntimeConfig) *libcni.RuntimeConf {
logging.Debugf("LoadCNIRuntimeConf: %v, %v, %s, %v", args, k8sArgs, ifName, rc)
// CreateCNIRuntimeConf create CNI RuntimeConf for a delegate. If delegate configuration
// exists, merge data with the runtime config.
func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, rc *RuntimeConfig, delegate *DelegateNetConf) (*libcni.RuntimeConf, string) {
logging.Debugf("LoadCNIRuntimeConf: %v, %v, %s, %v %v", args, k8sArgs, ifName, rc, delegate)
var cniDeviceInfoFile string
delegateRc := rc
if delegate != nil {
delegateRc = mergeCNIRuntimeConfig(delegateRc, delegate)
if delegateRc.CNIDeviceInfoFile == "" && delegate.Name != "" {
autoDeviceInfo := fmt.Sprintf("%s-%s_%s", delegate.Name, args.ContainerID, ifName)
delegateRc.CNIDeviceInfoFile = nadutils.GetCNIDeviceInfoPath(autoDeviceInfo)
cniDeviceInfoFile = delegateRc.CNIDeviceInfoFile
logging.Debugf("Adding auto-generated CNIDeviceInfoFile: %s", delegateRc.CNIDeviceInfoFile)
}
}
// In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go#buildCNIRuntimeConf
// Todo
@@ -179,26 +207,32 @@ func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, r
},
}
if rc != nil {
if delegateRc != nil {
capabilityArgs := map[string]interface{}{}
if len(rc.PortMaps) != 0 {
capabilityArgs["portMappings"] = rc.PortMaps
if len(delegateRc.PortMaps) != 0 {
capabilityArgs["portMappings"] = delegateRc.PortMaps
}
if rc.Bandwidth != nil {
capabilityArgs["bandwidth"] = rc.Bandwidth
if delegateRc.Bandwidth != nil {
capabilityArgs["bandwidth"] = delegateRc.Bandwidth
}
if len(rc.IPs) != 0 {
capabilityArgs["ips"] = rc.IPs
if len(delegateRc.IPs) != 0 {
capabilityArgs["ips"] = delegateRc.IPs
}
if len(rc.Mac) != 0 {
capabilityArgs["mac"] = rc.Mac
if len(delegateRc.Mac) != 0 {
capabilityArgs["mac"] = delegateRc.Mac
}
if len(rc.InfinibandGUID) != 0 {
capabilityArgs["infinibandGUID"] = rc.InfinibandGUID
if len(delegateRc.InfinibandGUID) != 0 {
capabilityArgs["infinibandGUID"] = delegateRc.InfinibandGUID
}
if delegateRc.DeviceID != "" {
capabilityArgs["deviceID"] = delegateRc.DeviceID
}
if delegateRc.CNIDeviceInfoFile != "" {
capabilityArgs["CNIDeviceInfoFile"] = delegateRc.CNIDeviceInfoFile
}
rt.CapabilityArgs = capabilityArgs
}
return rt
return rt, cniDeviceInfoFile
}
// GetGatewayFromResult retrieves gateway IP addresses from CNI result
@@ -292,7 +326,7 @@ func LoadNetConf(bytes []byte) (*NetConf, error) {
if err != nil {
return nil, logging.Errorf("LoadNetConf: error marshalling delegate %d config: %v", idx, err)
}
delegateConf, err := LoadDelegateNetConf(bytes, nil, "")
delegateConf, err := LoadDelegateNetConf(bytes, nil, "", "")
if err != nil {
return nil, logging.Errorf("LoadNetConf: failed to load delegate %d config: %v", idx, err)
}

View File

@@ -102,7 +102,7 @@ var _ = Describe("config operations", func() {
_, err := LoadNetConf([]byte(conf))
Expect(err).To(HaveOccurred())
_, err = LoadDelegateNetConf([]byte(conf), nil, "")
_, err = LoadDelegateNetConf([]byte(conf), nil, "", "")
Expect(err).To(HaveOccurred())
err = LoadDelegateNetConfList([]byte(conf), &DelegateNetConf{})
Expect(err).To(HaveOccurred())
@@ -280,7 +280,7 @@ var _ = Describe("config operations", func() {
DeviceID string `json:"deviceID"`
}
sriovConf := &sriovNetConf{}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "")
Expect(err).NotTo(HaveOccurred())
err = json.Unmarshal(delegateNetConf.Bytes, &sriovConf)
@@ -306,7 +306,7 @@ var _ = Describe("config operations", func() {
Plugins []*sriovNetConf `json:"plugins"`
}
sriovConfList := &sriovNetConfList{}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1", "")
Expect(err).NotTo(HaveOccurred())
err = json.Unmarshal(delegateNetConf.Bytes, &sriovConfList)
@@ -335,7 +335,7 @@ var _ = Describe("config operations", func() {
Plugins []*sriovNetConf `json:"plugins"`
}
sriovConfList := &sriovNetConfList{}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1", "")
Expect(err).NotTo(HaveOccurred())
err = json.Unmarshal(delegateNetConf.Bytes, &sriovConfList)
@@ -356,7 +356,7 @@ var _ = Describe("config operations", func() {
PCIBusID string `json:"pciBusID"`
}
hostDeviceConf := &hostDeviceNetConf{}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.2")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.2", "")
Expect(err).NotTo(HaveOccurred())
err = json.Unmarshal(delegateNetConf.Bytes, &hostDeviceConf)
@@ -382,7 +382,7 @@ var _ = Describe("config operations", func() {
Plugins []*hostDeviceNetConf `json:"plugins"`
}
hostDeviceConfList := &hostDeviceNetConfList{}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3", "")
Expect(err).NotTo(HaveOccurred())
err = json.Unmarshal(delegateNetConf.Bytes, &hostDeviceConfList)
@@ -411,7 +411,7 @@ var _ = Describe("config operations", func() {
Plugins []*hostDeviceNetConf `json:"plugins"`
}
hostDeviceConfList := &hostDeviceNetConfList{}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3", "")
Expect(err).NotTo(HaveOccurred())
err = json.Unmarshal(delegateNetConf.Bytes, &hostDeviceConfList)
@@ -444,7 +444,7 @@ var _ = Describe("config operations", func() {
Name: "test-elem",
CNIArgs: &args,
}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "", "")
Expect(err).NotTo(HaveOccurred())
bridgeConf := &bridgeNetConf{}
err = json.Unmarshal(delegateNetConf.Bytes, bridgeConf)
@@ -480,7 +480,7 @@ var _ = Describe("config operations", func() {
Name: "test-elem",
CNIArgs: &args,
}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "", "")
Expect(err).NotTo(HaveOccurred())
bridgeConf := &bridgeNetConf{}
err = json.Unmarshal(delegateNetConf.Bytes, bridgeConf)
@@ -518,7 +518,7 @@ var _ = Describe("config operations", func() {
Name: "test-elem",
CNIArgs: &args,
}
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "")
delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "", "")
Expect(err).NotTo(HaveOccurred())
bridgeConflist := &bridgeNetConfList{}
err = json.Unmarshal(delegateNetConf.Bytes, bridgeConflist)
@@ -565,7 +565,7 @@ var _ = Describe("config operations", func() {
HostIP: "anotherSampleHostIP",
}
rt := CreateCNIRuntimeConf(args, k8sArgs, "", rc)
rt, _ := CreateCNIRuntimeConf(args, k8sArgs, "", rc, nil)
fmt.Println("rt.ContainerID: ", rt.ContainerID)
Expect(rt.ContainerID).To(Equal("123456789"))
Expect(rt.NetNS).To(Equal(args.Netns))
@@ -595,10 +595,10 @@ var _ = Describe("config operations", func() {
}
}`
delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "")
Expect(err).NotTo(HaveOccurred())
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
@@ -628,10 +628,10 @@ var _ = Describe("config operations", func() {
}
}`
delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0")
delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "")
Expect(err).NotTo(HaveOccurred())
fmt.Println("result.Version: ", result.Version())
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil)
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
@@ -668,7 +668,7 @@ var _ = Describe("config operations", func() {
PortMappingsRequest: []*PortMapEntry{portMapEntry1},
}
delegateConf, err := LoadDelegateNetConf([]byte(cniConfig), networkSelection, "")
delegateConf, err := LoadDelegateNetConf([]byte(cniConfig), networkSelection, "", "")
Expect(err).NotTo(HaveOccurred())
Expect(delegateConf.IfnameRequest).To(Equal(networkSelection.InterfaceRequest))
Expect(delegateConf.MacRequest).To(Equal(networkSelection.MacRequest))
@@ -678,7 +678,7 @@ var _ = Describe("config operations", func() {
Expect(delegateConf.PortMappingsRequest).To(Equal(networkSelection.PortMappingsRequest))
})
It("test MergeCNIRuntimeConfig with masterPlugin", func() {
It("test mergeCNIRuntimeConfig with masterPlugin", func() {
conf := `{
"name": "node-cni-network",
"type": "multus",
@@ -714,16 +714,16 @@ var _ = Describe("config operations", func() {
BandwidthRequest: bandwidthEntry1,
PortMappingsRequest: []*PortMapEntry{portMapEntry1},
}
delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "")
delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "", "")
delegate.MasterPlugin = true
Expect(err).NotTo(HaveOccurred())
runtimeConf := MergeCNIRuntimeConfig(&RuntimeConfig{}, delegate)
runtimeConf := mergeCNIRuntimeConfig(&RuntimeConfig{}, delegate)
Expect(runtimeConf.PortMaps).To(BeNil())
Expect(runtimeConf.Bandwidth).To(BeNil())
Expect(runtimeConf.InfinibandGUID).To(Equal(""))
})
It("test MergeCNIRuntimeConfig with delegate plugin", func() {
It("test mergeCNIRuntimeConfig with delegate plugin", func() {
conf := `{
"name": "weave1",
"cniVersion": "0.2.0",
@@ -751,9 +751,9 @@ var _ = Describe("config operations", func() {
BandwidthRequest: bandwidthEntry1,
PortMappingsRequest: []*PortMapEntry{portMapEntry1},
}
delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "")
delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "", "")
Expect(err).NotTo(HaveOccurred())
runtimeConf := MergeCNIRuntimeConfig(&RuntimeConfig{}, delegate)
runtimeConf := mergeCNIRuntimeConfig(&RuntimeConfig{}, delegate)
Expect(runtimeConf.PortMaps).NotTo(BeNil())
Expect(len(runtimeConf.PortMaps)).To(BeEquivalentTo(1))
Expect(runtimeConf.PortMaps[0]).To(Equal(portMapEntry1))

View File

@@ -38,7 +38,6 @@ type NetConf struct {
// RawDelegates is private to the NetConf class; use Delegates instead
RawDelegates []map[string]interface{} `json:"delegates"`
Delegates []*DelegateNetConf `json:"-"`
NetStatus []*NetworkStatus `json:"-"`
Kubeconfig string `json:"kubeconfig"`
ClusterNetwork string `json:"clusterNetwork"`
DefaultNetworks []string `json:"defaultNetworks"`
@@ -57,11 +56,13 @@ type NetConf struct {
// RuntimeConfig specifies CNI RuntimeConfig
type RuntimeConfig struct {
PortMaps []*PortMapEntry `json:"portMappings,omitempty"`
Bandwidth *BandwidthEntry `json:"bandwidth,omitempty"`
IPs []string `json:"ips,omitempty"`
Mac string `json:"mac,omitempty"`
InfinibandGUID string `json:"infinibandGUID,omitempty"`
PortMaps []*PortMapEntry `json:"portMappings,omitempty"`
Bandwidth *BandwidthEntry `json:"bandwidth,omitempty"`
IPs []string `json:"ips,omitempty"`
Mac string `json:"mac,omitempty"`
InfinibandGUID string `json:"infinibandGUID,omitempty"`
DeviceID string `json:"deviceID,omitempty"`
CNIDeviceInfoFile string `json:"CNIDeviceInfoFile,omitempty"`
}
// PortMapEntry for CNI PortMapEntry
@@ -81,16 +82,6 @@ type BandwidthEntry struct {
EgressBurst int `json:"egressBurst"`
}
// NetworkStatus is for network status annotation for pod
type NetworkStatus struct {
Name string `json:"name"`
Interface string `json:"interface,omitempty"`
IPs []string `json:"ips,omitempty"`
Mac string `json:"mac,omitempty"`
DNS types.DNS `json:"dns,omitempty"`
Gateway []net.IP `json:"default-route,omitempty"`
}
// DelegateNetConf for net-attach-def for pod
type DelegateNetConf struct {
Conf types.NetConf
@@ -108,6 +99,10 @@ type DelegateNetConf struct {
MasterPlugin bool `json:"-"`
// Conflist plugin is only used internal housekeeping
ConfListPlugin bool `json:"-"`
// DeviceID is only used internal housekeeping
DeviceID string `json:"deviceID,omitempty"`
// ResourceName is only used internal housekeeping
ResourceName string `json:"resourceName,omitempty"`
// Raw JSON
Bytes []byte
@@ -143,6 +138,8 @@ type NetworkSelectionElement struct {
// BandwidthRequest contains an optional requested bandwidth for
// the network
BandwidthRequest *BandwidthEntry `json:"bandwidth,omitempty"`
// DeviceID contains an optional requested deviceID the network
DeviceID string `json:"deviceID,omitempty"`
// CNIArgs contains additional CNI arguments for the network interface
CNIArgs *map[string]interface{} `json:"cni-args"`
// GatewayRequest contains default route IP address for the pod

View File

@@ -38,15 +38,74 @@ type DNS struct {
Options []string `json:"options,omitempty"`
}
const (
DeviceInfoTypePCI = "pci"
DeviceInfoTypeVHostUser = "vhost-user"
DeviceInfoTypeMemif = "memif"
DeviceInfoTypeVDPA = "vdpa"
DeviceInfoVersion = "1.0.0"
)
// DeviceInfo contains the information of the device associated
// with this network (if any)
type DeviceInfo struct {
Type string `json:"type,omitempty"`
Version string `json:"version,omitempty"`
Pci *PciDevice `json:"pci,omitempty"`
Vdpa *VdpaDevice `json:"vdpa,omitempty"`
VhostUser *VhostDevice `json:"vhost-user,omitempty"`
Memif *MemifDevice `json:"memif,omitempty"`
}
type PciDevice struct {
PciAddress string `json:"pci-address,omitempty"`
Vhostnet string `json:"vhost-net,omitempty"`
RdmaDevice string `json:"rdma-device,omitempty"`
PfPciAddress string `json:"pf-pci-address,omitempty"`
}
type VdpaDevice struct {
ParentDevice string `json:"parent-device,omitempty"`
Driver string `json:"driver,omitempty"`
Path string `json:"path,omitempty"`
PciAddress string `json:"pci-address,omitempty"`
PfPciAddress string `json:"pf-pci-address,omitempty"`
}
const (
VhostDeviceModeClient = "client"
VhostDeviceModeServer = "server"
)
type VhostDevice struct {
Mode string `json:"mode,omitempty"`
Path string `json:"path,omitempty"`
}
const (
MemifDeviceRoleMaster = "master"
MemitDeviceRoleSlave = "slave"
MemifDeviceModeEthernet = "ethernet"
MemitDeviceModeIP = "ip"
MemitDeviceModePunt = "punt"
)
type MemifDevice struct {
Role string `json:"role,omitempty"`
Path string `json:"path,omitempty"`
Mode string `json:"mode,omitempty"`
}
// NetworkStatus is for network status annotation for pod
// +k8s:deepcopy-gen=false
type NetworkStatus struct {
Name string `json:"name"`
Interface string `json:"interface,omitempty"`
IPs []string `json:"ips,omitempty"`
Mac string `json:"mac,omitempty"`
Default bool `json:"default,omitempty"`
DNS DNS `json:"dns,omitempty"`
Name string `json:"name"`
Interface string `json:"interface,omitempty"`
IPs []string `json:"ips,omitempty"`
Mac string `json:"mac,omitempty"`
Default bool `json:"default,omitempty"`
DNS DNS `json:"dns,omitempty"`
DeviceInfo *DeviceInfo `json:"device-info,omitempty"`
}
// PortMapEntry for CNI PortMapEntry

View File

@@ -24,6 +24,58 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DeviceInfo) DeepCopyInto(out *DeviceInfo) {
*out = *in
if in.Pci != nil {
in, out := &in.Pci, &out.Pci
*out = new(PciDevice)
**out = **in
}
if in.Vdpa != nil {
in, out := &in.Vdpa, &out.Vdpa
*out = new(VdpaDevice)
**out = **in
}
if in.VhostUser != nil {
in, out := &in.VhostUser, &out.VhostUser
*out = new(VhostDevice)
**out = **in
}
if in.Memif != nil {
in, out := &in.Memif, &out.Memif
*out = new(MemifDevice)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceInfo.
func (in *DeviceInfo) DeepCopy() *DeviceInfo {
if in == nil {
return nil
}
out := new(DeviceInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MemifDevice) DeepCopyInto(out *MemifDevice) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemifDevice.
func (in *MemifDevice) DeepCopy() *MemifDevice {
if in == nil {
return nil
}
out := new(MemifDevice)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NetworkAttachmentDefinition) DeepCopyInto(out *NetworkAttachmentDefinition) {
*out = *in
@@ -99,3 +151,51 @@ func (in *NetworkAttachmentDefinitionSpec) DeepCopy() *NetworkAttachmentDefiniti
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PciDevice) DeepCopyInto(out *PciDevice) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PciDevice.
func (in *PciDevice) DeepCopy() *PciDevice {
if in == nil {
return nil
}
out := new(PciDevice)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VdpaDevice) DeepCopyInto(out *VdpaDevice) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VdpaDevice.
func (in *VdpaDevice) DeepCopy() *VdpaDevice {
if in == nil {
return nil
}
out := new(VdpaDevice)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VhostDevice) DeepCopyInto(out *VhostDevice) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VhostDevice.
func (in *VhostDevice) DeepCopy() *VhostDevice {
if in == nil {
return nil
}
out := new(VhostDevice)
in.DeepCopyInto(out)
return out
}

View File

@@ -18,11 +18,20 @@ import (
"encoding/json"
"fmt"
"github.com/containernetworking/cni/libcni"
"io/ioutil"
"os"
"path/filepath"
"strings"
v1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
)
const (
baseDevInfoPath = "/var/run/k8s.cni.cncf.io/devinfo"
dpDevInfoSubDir = "dp"
cniDevInfoSubDir = "cni"
)
// GetCNIConfig (from annotation string to CNI JSON bytes)
func GetCNIConfig(net *v1.NetworkAttachmentDefinition, confDir string) (config []byte, err error) {
emptySpec := v1.NetworkAttachmentDefinitionSpec{}
@@ -117,3 +126,112 @@ func GetCNIConfigFromSpec(configData, netName string) ([]byte, error) {
return configBytes, nil
}
// loadDeviceInfo loads a Device Information file
func loadDeviceInfo(path string) (*v1.DeviceInfo, error) {
var devInfo v1.DeviceInfo
bytes, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
err = json.Unmarshal(bytes, &devInfo)
if err != nil {
return nil, err
}
return &devInfo, nil
}
// cleanDeviceInfo removes a Device Information file
func cleanDeviceInfo(path string) error {
if _, err := os.Stat(path); !os.IsNotExist(err) {
return os.Remove(path)
}
return nil
}
// saveDeviceInfo writes a Device Information file
func saveDeviceInfo(devInfo *v1.DeviceInfo, path string) error {
if devInfo == nil {
return fmt.Errorf("Device Information is null")
}
dir := filepath.Dir(path)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModeDir); err != nil {
return err
}
}
if _, err := os.Stat(path); !os.IsNotExist(err) {
return fmt.Errorf("Device Information file already exists: %s", path)
}
devInfoJSON, err := json.Marshal(devInfo)
if err != nil {
return err
}
if err := ioutil.WriteFile(path, devInfoJSON, 0444); err != nil {
return err
}
return nil
}
// getDPDeviceInfoPath returns the standard Device Plugin DevInfo filename
// This filename is fixed because Device Plugin and NPWG Implementation need
// to both access file and name is not passed between them. So name is generated
// from Resource Name and DeviceID.
func getDPDeviceInfoPath(resourceName string, deviceID string) string {
return filepath.Join(baseDevInfoPath, dpDevInfoSubDir, fmt.Sprintf("%s-%s-device.json",
strings.ReplaceAll(resourceName, "/", "-"), strings.ReplaceAll(deviceID, "/", "-")))
}
// GetCNIDeviceInfoPath returns the standard Device Plugin DevInfo filename
// The path is fixed but the filename is flexible and determined by the caller.
func GetCNIDeviceInfoPath(filename string) string {
return filepath.Join(baseDevInfoPath, cniDevInfoSubDir, strings.ReplaceAll(filename, "/", "-"))
}
// LoadDeviceInfoFromDP loads a DeviceInfo structure from file created by a Device Plugin
// Returns an error if the device information is malformed and (nil, nil) if it does not exist
func LoadDeviceInfoFromDP(resourceName string, deviceID string) (*v1.DeviceInfo, error) {
return loadDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID))
}
// SaveDeviceInfoForDP saves a DeviceInfo structure created by a Device Plugin
func SaveDeviceInfoForDP(resourceName string, deviceID string, devInfo *v1.DeviceInfo) error {
return saveDeviceInfo(devInfo, getDPDeviceInfoPath(resourceName, deviceID))
}
// CleanDeviceInfoForDP removes a DeviceInfo DP File.
func CleanDeviceInfoForDP(resourceName string, deviceID string) error {
return cleanDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID))
}
// LoadDeviceInfoFromCNI loads a DeviceInfo structure from created by a CNI.
// Returns an error if the device information is malformed and (nil, nil) if it does not exist
func LoadDeviceInfoFromCNI(cniPath string) (*v1.DeviceInfo, error) {
return loadDeviceInfo(cniPath)
}
// SaveDeviceInfoForCNI saves a DeviceInfo structure created by a CNI
func SaveDeviceInfoForCNI(cniPath string, devInfo *v1.DeviceInfo) error {
return saveDeviceInfo(devInfo, cniPath)
}
// CopyDeviceInfoForCNIFromDP saves a DeviceInfo structure created by a DP to a CNI File.
func CopyDeviceInfoForCNIFromDP(cniPath string, resourceName string, deviceID string) error {
devInfo, err := loadDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID))
if err != nil {
return err
}
return saveDeviceInfo(devInfo, cniPath)
}
// CleanDeviceInfoForCNI removes a DeviceInfo CNI File.
func CleanDeviceInfoForCNI(cniPath string) error {
return cleanDeviceInfo(cniPath)
}

View File

@@ -122,7 +122,7 @@ func GetNetworkStatus(pod *corev1.Pod) ([]v1.NetworkStatus, error) {
}
// CreateNetworkStatus create NetworkStatus from CNI result
func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool) (*v1.NetworkStatus, error) {
func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) (*v1.NetworkStatus, error) {
netStatus := &v1.NetworkStatus{}
netStatus.Name = networkName
netStatus.Default = defaultNetwork
@@ -154,6 +154,10 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b
v1dns := convertDNS(result.DNS)
netStatus.DNS = *v1dns
if dev != nil {
netStatus.DeviceInfo = dev
}
return netStatus, nil
}

2
vendor/modules.txt vendored
View File

@@ -45,7 +45,7 @@ github.com/hpcloud/tail/winfile
github.com/imdario/mergo
# github.com/json-iterator/go v1.1.9
github.com/json-iterator/go
# github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc
# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d
github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io
github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1
github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/clientset/versioned