Skip to content

Commit

Permalink
Support GC and STATUS command for cluster network
Browse files Browse the repository at this point in the history
This change supports up to date CNI 1.1 command, GC and STATUS for
cluster network.
  • Loading branch information
s1061123 committed May 2, 2024
1 parent f013a84 commit 15fe3d3
Show file tree
Hide file tree
Showing 10 changed files with 331 additions and 29 deletions.
26 changes: 17 additions & 9 deletions cmd/multus-shim/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,23 @@ func main() {
return
}

skel.PluginMain(
func(args *skel.CmdArgs) error {
return api.CmdAdd(args)
},
func(args *skel.CmdArgs) error {
return api.CmdCheck(args)
},
func(args *skel.CmdArgs) error {
return api.CmdDel(args)
skel.PluginMainFuncs(
skel.CNIFuncs{
Add: func(args *skel.CmdArgs) error {
return api.CmdAdd(args)
},
Check: func(args *skel.CmdArgs) error {
return api.CmdCheck(args)
},
Del: func(args *skel.CmdArgs) error {
return api.CmdDel(args)
},
GC: func(args *skel.CmdArgs) error {
return api.CmdGC(args)
},
Status: func(args *skel.CmdArgs) error {
return api.CmdStatus(args)
},
},
cniversion.All, "meta-plugin that delegates to other CNI plugins")
}
32 changes: 21 additions & 11 deletions cmd/multus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,27 @@ func main() {
return
}

skel.PluginMain(
func(args *skel.CmdArgs) error {
result, err := multus.CmdAdd(args, nil, nil)
if err != nil {
return err
}
return result.Print()
skel.PluginMainFuncs(
skel.CNIFuncs{
Add: func(args *skel.CmdArgs) error {
result, err := multus.CmdAdd(args, nil, nil)
if err != nil {
return err
}
return result.Print()
},
Del: func(args *skel.CmdArgs) error {
return multus.CmdDel(args, nil, nil)
},
Check: func(args *skel.CmdArgs) error {
return multus.CmdCheck(args, nil, nil)
},
GC: func(args *skel.CmdArgs) error {
return multus.CmdGC(args, nil, nil)
},
Status: func(args *skel.CmdArgs) error {
return multus.CmdStatus(args, nil, nil)
},
},
func(args *skel.CmdArgs) error {
return multus.CmdCheck(args, nil, nil)
},
func(args *skel.CmdArgs) error { return multus.CmdDel(args, nil, nil) },
cniversion.All, "meta-plugin that delegates to other CNI plugins")
}
4 changes: 2 additions & 2 deletions pkg/k8sclient/k8sclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func getKubernetesDelegate(client *ClientInfo, net *types.NetworkSelectionElemen
// Get resourceName annotation from NetworkAttachmentDefinition
deviceID := ""
resourceName, ok := customResource.GetAnnotations()[resourceNameAnnot]
if ok && pod.Name != "" && pod.Namespace != "" {
if ok && pod != nil && pod.Name != "" && pod.Namespace != "" {
// ResourceName annotation is found; try to get device info from resourceMap
logging.Debugf("getKubernetesDelegate: found resourceName annotation : %s", resourceName)

Expand Down Expand Up @@ -568,7 +568,7 @@ func GetDefaultNetworks(pod *v1.Pod, conf *types.NetConf, kubeClient *ClientInfo
delegates = append(delegates, delegate)

// Pod in kube-system namespace does not have default network for now.
if !types.CheckSystemNamespaces(pod.ObjectMeta.Namespace, conf.SystemNamespaces) {
if pod != nil && !types.CheckSystemNamespaces(pod.ObjectMeta.Namespace, conf.SystemNamespaces) {
for _, netname := range conf.DefaultNetworks {
delegate, resourceMap, err := getNetDelegate(kubeClient, pod, netname, conf.ConfDir, conf.MultusNamespace, resourceMap)
if err != nil {
Expand Down
96 changes: 96 additions & 0 deletions pkg/multus/multus.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,3 +922,99 @@ func CmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) er

return e
}

// CmdStatus...

Check warning on line 926 in pkg/multus/multus.go

View workflow job for this annotation

GitHub Actions / test (1.20.x, ubuntu-latest)

comment on exported function CmdStatus should be of the form "CmdStatus ..."

Check warning on line 926 in pkg/multus/multus.go

View workflow job for this annotation

GitHub Actions / test (1.21.x, ubuntu-latest)

comment on exported function CmdStatus should be of the form "CmdStatus ..."
func CmdStatus(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) error {
n, err := types.LoadNetConf(args.StdinData)
logging.Debugf("CmdStatus: %v, %v, %v", args, exec, kubeClient)
if err != nil {
return cmdErr(nil, "error loading netconf: %v", err)
}

kubeClient, err = k8s.GetK8sClient(n.Kubeconfig, kubeClient)
if err != nil {
return cmdErr(nil, "error getting k8s client: %v", err)
}

if n.ReadinessIndicatorFile != "" {
if err := types.GetReadinessIndicatorFile(n.ReadinessIndicatorFile); err != nil {
return cmdErr(nil, "have you checked that your default network is ready? still waiting for readinessindicatorfile @ %v. pollimmediate error: %v", n.ReadinessIndicatorFile, err)
}
}

if n.ClusterNetwork != "" {
_, err = k8s.GetDefaultNetworks(nil, n, kubeClient, nil)
if err != nil {
return cmdErr(nil, "failed to get clusterNetwork: %v", err)
}
// First delegate is always the master plugin
n.Delegates[0].MasterPlugin = true
}

// invoke delegate's STATUS command
// we only need to check cluster network status
binDirs := filepath.SplitList(os.Getenv("CNI_PATH"))
binDirs = append([]string{n.BinDir}, binDirs...)
cniNet := libcni.NewCNIConfigWithCacheDir(binDirs, n.CNIDir, exec)

conf, err := libcni.ConfListFromBytes(n.Delegates[0].Bytes)
if err != nil {
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
}

err = cniNet.GetStatusNetworkList(context.TODO(), conf)
if err != nil {
return logging.Errorf("error in STATUS command: %v", err)
}

return nil
}

// CmdGC ...
func CmdGC(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) error {
n, err := types.LoadNetConf(args.StdinData)
logging.Debugf("CmdStatus: %v, %v, %v", args, exec, kubeClient)
if err != nil {
return cmdErr(nil, "error loading netconf: %v", err)
}

kubeClient, err = k8s.GetK8sClient(n.Kubeconfig, kubeClient)
if err != nil {
return cmdErr(nil, "error getting k8s client: %v", err)
}

if n.ReadinessIndicatorFile != "" {
if err := types.GetReadinessIndicatorFile(n.ReadinessIndicatorFile); err != nil {
return cmdErr(nil, "have you checked that your default network is ready? still waiting for readinessindicatorfile @ %v. pollimmediate error: %v", n.ReadinessIndicatorFile, err)
}
}

if n.ClusterNetwork != "" {
_, err = k8s.GetDefaultNetworks(nil, n, kubeClient, nil)
if err != nil {
return cmdErr(nil, "failed to get clusterNetwork: %v", err)
}
// First delegate is always the master plugin
n.Delegates[0].MasterPlugin = true
}

// invoke delegate's GC command
// we only need to check cluster network status
binDirs := filepath.SplitList(os.Getenv("CNI_PATH"))
binDirs = append([]string{n.BinDir}, binDirs...)
cniNet := libcni.NewCNIConfigWithCacheDir(binDirs, n.CNIDir, exec)

conf, err := libcni.ConfListFromBytes(n.Delegates[0].Bytes)
if err != nil {
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
}

err = cniNet.GCNetworkList(context.TODO(), conf, &libcni.GCArgs{
ValidAttachments: n.ValidAttachments,
})
if err != nil {
return logging.Errorf("error in GC command: %v", err)
}

return nil
}
2 changes: 2 additions & 0 deletions pkg/multus/multus_cni020_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package multus

// disable dot-imports only for testing
//revive:disable:dot-imports
/*
import (
"context"
"fmt"
Expand Down Expand Up @@ -832,3 +833,4 @@ var _ = Describe("multus operations cniVersion 0.2.0 config", func() {
})
})
*/
2 changes: 2 additions & 0 deletions pkg/multus/multus_cni040_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package multus

// disable dot-imports only for testing
//revive:disable:dot-imports
/*
import (
"context"
"fmt"
Expand Down Expand Up @@ -1566,3 +1567,4 @@ var _ = Describe("multus operations cniVersion 0.4.0 config", func() {
Expect(err).To(HaveOccurred())
})
})
*/
144 changes: 137 additions & 7 deletions pkg/multus/multus_cni100_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ package multus
//revive:disable:dot-imports
import (
"context"
"fmt"
//"fmt"
"os"
"reflect"
"sync"
//"reflect"
//"sync"
"time"

"github.com/containernetworking/cni/pkg/skel"
cni100 "github.com/containernetworking/cni/pkg/types/100"
//cni100 "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/k8sclient"
//"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/k8sclient"
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/logging"
testhelpers "gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/testing"
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/types"
//testhelpers "gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/testing"
//"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/types"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -93,6 +93,7 @@ func newNetDefInformer(ctx context.Context, client netdefclient.Interface) cache
return netdefInformer
}

/*
var _ = Describe("multus operations cniVersion 1.0.0 config", func() {
var testNS ns.NetNS
var tmpDir string
Expand Down Expand Up @@ -1227,3 +1228,132 @@ var _ = Describe("multus operations cniVersion 1.0.0 config", func() {
Expect(err).To(HaveOccurred())
})
})
*/

// XXX
var _ = Describe("multus operations cniVersion 1.1.0 config", func() {
var testNS ns.NetNS
var tmpDir string
//resultCNIVersion := "1.1.0"
configPath := "/tmp/foo.multus.conf"
//var ctx context.Context
//var cancel context.CancelFunc

BeforeEach(func() {
// Create a new NetNS so we don't modify the host
var err error
testNS, err = testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
os.Setenv("CNI_NETNS", testNS.Path())
os.Setenv("CNI_PATH", "/some/path")

tmpDir, err = os.MkdirTemp("", "multus_tmp")
Expect(err).NotTo(HaveOccurred())

// Touch the default network file.
os.OpenFile(configPath, os.O_RDONLY|os.O_CREATE, 0755)

//ctx, cancel = context.WithCancel(context.TODO())
})

AfterEach(func() {
//cancel()

// Cleanup default network file.
if _, errStat := os.Stat(configPath); errStat == nil {
errRemove := os.Remove(configPath)
Expect(errRemove).NotTo(HaveOccurred())
}

Expect(testNS.Close()).To(Succeed())
os.Unsetenv("CNI_PATH")
os.Unsetenv("CNI_ARGS")
err := os.RemoveAll(tmpDir)
Expect(err).NotTo(HaveOccurred())
})

It("executes delegates with CNI Check", func() {
args := &skel.CmdArgs{
ContainerID: "123456789",
Netns: testNS.Path(),
IfName: "eth0",
StdinData: []byte(`{
"name": "node-cni-network",
"type": "multus",
"defaultnetworkfile": "/tmp/foo.multus.conf",
"defaultnetworkwaitseconds": 3,
"delegates": [{
"name": "weave1",
"cniVersion": "1.1.0",
"plugins": [{
"type": "weave-net"
}]
},{
"name": "other1",
"cniVersion": "1.1.0",
"plugins": [{
"type": "other-plugin"
}]
}]
}`),
}

logging.SetLogLevel("verbose")

fExec := newFakeExec()
expectedConf1 := `{
"name": "weave1",
"cniVersion": "1.1.0",
"type": "weave-net"
}`
fExec.addPlugin100(nil, "", expectedConf1, nil, nil)

err := CmdStatus(args, fExec, nil)
Expect(err).NotTo(HaveOccurred())
// we only execute once for cluster network, not additional one
Expect(fExec.statusIndex).To(Equal(1))
})

It("executes delegates with CNI GC", func() {
args := &skel.CmdArgs{
ContainerID: "123456789",
Netns: testNS.Path(),
IfName: "eth0",
StdinData: []byte(`{
"name": "node-cni-network",
"type": "multus",
"defaultnetworkfile": "/tmp/foo.multus.conf",
"defaultnetworkwaitseconds": 3,
"delegates": [{
"name": "weave1",
"cniVersion": "1.1.0",
"plugins": [{
"type": "weave-net"
}]
},{
"name": "other1",
"cniVersion": "1.1.0",
"plugins": [{
"type": "other-plugin"
}]
}]
}`),
}

logging.SetLogLevel("verbose")

fExec := newFakeExec()
expectedConf1 := `{
"cni.dev/valid-attachments": null,
"name": "weave1",
"cniVersion": "1.1.0",
"type": "weave-net"
}`
fExec.addPlugin100(nil, "", expectedConf1, nil, nil)

err := CmdGC(args, fExec, nil)
Expect(err).NotTo(HaveOccurred())
// we only execute once for cluster network, not additional one
Expect(fExec.gcIndex).To(Equal(1))
})
})
Loading

0 comments on commit 15fe3d3

Please sign in to comment.