Skip to content

Commit

Permalink
add support for cni STATUS verb
Browse files Browse the repository at this point in the history
The new CNI v1.1 STATUS verb allows for plugins to report that they are not ready
to handle ADDs. It is a cleaner API than the awkward
"remove-config-file" dance currently in use.

The libcni code gracefully handles older versions, so this is backwards
compatible.

Signed-off-by: Casey Callendrello <[email protected]>
  • Loading branch information
squeed committed Apr 16, 2024
1 parent 809df9b commit 37df39a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
16 changes: 14 additions & 2 deletions pkg/ocicni/ocicni.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,10 @@ func (network *cniNetwork) deleteFromNetwork(ctx context.Context, rt *libcni.Run
return cni.DelNetworkList(ctx, network.config, rt)
}

func (network *cniNetwork) getNetworkStatus(ctx context.Context, cni *libcni.CNIConfig) error {
return cni.GetStatusNetworkList(ctx, network.config)
}

func buildCNIRuntimeConf(podNetwork *PodNetwork, ifName string, runtimeConfig *RuntimeConfig) (*libcni.RuntimeConf, error) {
if runtimeConfig == nil {
runtimeConfig = &RuntimeConfig{}
Expand Down Expand Up @@ -887,9 +891,17 @@ func buildCNIRuntimeConf(podNetwork *PodNetwork, ifName string, runtimeConfig *R
return rt, nil
}

// Status returns error if the default network is not configured, or if
// the default network reports a failing STATUS code.
func (plugin *cniNetworkPlugin) Status() error {
if plugin.getDefaultNetwork() == nil {
return plugin.StatusWithContext(context.Background())
}

func (plugin *cniNetworkPlugin) StatusWithContext(ctx context.Context) error {
defaultNet := plugin.getDefaultNetwork()
if defaultNet == nil {
return fmt.Errorf(errMissingDefaultNetwork, plugin.confDir)
}
return nil

return defaultNet.getNetworkStatus(ctx, plugin.cniConfig)
}
25 changes: 22 additions & 3 deletions pkg/ocicni/ocicni_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ type fakeExec struct {
plugins []*fakePlugin

failFind bool

failStatus bool
}

type TestConf struct {
Expand Down Expand Up @@ -132,6 +134,11 @@ func (f *fakeExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData
case "VERSION":
// Just return all supported versions
return json.Marshal(version.All)
case "STATUS":
if f.failStatus {
return nil, errors.New("status fails")
}
return nil, nil
default:
// Should never be reached
Expect(false).To(BeTrue())
Expand Down Expand Up @@ -363,9 +370,13 @@ var _ = Describe("ocicni operations", func() {
})

It("finds and refinds an asynchronously written default network configuration", func() {
ocicni, err := initCNI(&fakeExec{}, "", "test", tmpDir, true, "/opt/cni/bin")
f := &fakeExec{}
ocicni, err := initCNI(f, "", "test", tmpDir, true, "/opt/cni/bin")
Expect(err).NotTo(HaveOccurred())

err = ocicni.Status()
Expect(err).To(HaveOccurred())

// Write the default network config
_, confPath, err := writeConfig(tmpDir, "10-test.conf", "test", "myplugin", "0.3.1")
Expect(err).NotTo(HaveOccurred())
Expand All @@ -384,12 +395,20 @@ var _ = Describe("ocicni operations", func() {
Expect(err).NotTo(HaveOccurred())
Eventually(ocicni.Status, 5).Should(HaveOccurred())

// Write the default network config again and wait for status
// Write the default network config again, this time with v1.1, and wait for status
// to be OK
_, _, err = writeConfig(tmpDir, "10-test.conf", "test", "myplugin", "0.3.1")
_, _, err = writeConfig(tmpDir, "10-test.conf", "test", "myplugin", "1.1.0")
Expect(err).NotTo(HaveOccurred())
Eventually(ocicni.Status, 5).Should(Succeed())

f.failStatus = true
err = ocicni.Status()
Expect(err).To(HaveOccurred())

f.failStatus = false
err = ocicni.Status()
Expect(err).NotTo(HaveOccurred())

Expect(ocicni.Shutdown()).NotTo(HaveOccurred())
})

Expand Down
4 changes: 4 additions & 0 deletions pkg/ocicni/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ type NetResult struct {
}

// CNIPlugin is the interface that needs to be implemented by a plugin.
//
//nolint:interfacebloat // existing API
type CNIPlugin interface {
// Name returns the plugin's name. This will be used when searching
// for a plugin by name, e.g.
Expand Down Expand Up @@ -157,6 +159,8 @@ type CNIPlugin interface {
// NetworkStatus returns error if the network plugin is in error state
Status() error

StatusWithContext(ctx context.Context) error

// Shutdown terminates all driver operations
Shutdown() error
}

0 comments on commit 37df39a

Please sign in to comment.