skel: Plugins require a cniVersion in the NetConf
This commit is contained in:
parent
de91f31ae7
commit
921292ff77
@ -16,6 +16,7 @@ package invoke
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
@ -77,7 +78,8 @@ func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, erro
|
||||
IfName: "dummy",
|
||||
Path: "dummy",
|
||||
}
|
||||
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, nil, args.AsEnv())
|
||||
stdin := []byte(fmt.Sprintf(`{"cniVersion":%q}`, version.Current()))
|
||||
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, stdin, args.AsEnv())
|
||||
if err != nil {
|
||||
if err.Error() == "unknown CNI_COMMAND: VERSION" {
|
||||
return version.PluginSupports("0.1.0"), nil
|
||||
|
@ -15,6 +15,7 @@
|
||||
package invoke_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
@ -48,7 +49,7 @@ var _ = Describe("Executing a plugin, unit tests", func() {
|
||||
VersionDecoder: versionDecoder,
|
||||
}
|
||||
pluginPath = "/some/plugin/path"
|
||||
netconf = []byte(`{ "some": "stdin" }`)
|
||||
netconf = []byte(`{ "some": "stdin", "cniVersion": "0.2.0" }`)
|
||||
cniargs = &fakes.CNIArgs{}
|
||||
cniargs.AsEnvCall.Returns.Env = []string{"SOME=ENV"}
|
||||
})
|
||||
@ -105,8 +106,9 @@ var _ = Describe("Executing a plugin, unit tests", func() {
|
||||
It("execs the plugin with the command VERSION", func() {
|
||||
pluginExec.GetVersionInfo(pluginPath)
|
||||
Expect(rawExec.ExecPluginCall.Received.PluginPath).To(Equal(pluginPath))
|
||||
Expect(rawExec.ExecPluginCall.Received.StdinData).To(BeNil())
|
||||
Expect(rawExec.ExecPluginCall.Received.Environ).To(ContainElement("CNI_COMMAND=VERSION"))
|
||||
expectedStdin, _ := json.Marshal(map[string]string{"cniVersion": version.Current()})
|
||||
Expect(rawExec.ExecPluginCall.Received.StdinData).To(MatchJSON(expectedStdin))
|
||||
})
|
||||
|
||||
It("decodes and returns the version info", func() {
|
||||
@ -146,6 +148,5 @@ var _ = Describe("Executing a plugin, unit tests", func() {
|
||||
Expect(env).To(ContainElement("CNI_PATH=dummy"))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
@ -58,7 +58,7 @@ var _ = Describe("RawExec", func() {
|
||||
"CNI_PATH=/some/bin/path",
|
||||
"CNI_IFNAME=some-eth0",
|
||||
}
|
||||
stdin = []byte(`{"some":"stdin-json"}`)
|
||||
stdin = []byte(`{"some":"stdin-json", "cniVersion": "0.2.0"}`)
|
||||
execer = &invoke.RawExec{}
|
||||
})
|
||||
|
||||
|
17
skel/skel.go
17
skel/skel.go
@ -17,6 +17,7 @@
|
||||
package skel
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -143,12 +144,28 @@ func createTypedError(f string, args ...interface{}) *types.Error {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *dispatcher) validateVersion(stdinData []byte) error {
|
||||
var netconf types.NetConf
|
||||
if err := json.Unmarshal(stdinData, &netconf); err != nil {
|
||||
return err
|
||||
}
|
||||
if netconf.CNIVersion == "" {
|
||||
return fmt.Errorf("missing required config cniVersion")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *dispatcher) pluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo) *types.Error {
|
||||
cmd, cmdArgs, err := t.getCmdArgsFromEnv()
|
||||
if err != nil {
|
||||
return createTypedError(err.Error())
|
||||
}
|
||||
|
||||
if err = t.validateVersion(cmdArgs.StdinData); err != nil {
|
||||
return createTypedError(err.Error())
|
||||
}
|
||||
|
||||
switch cmd {
|
||||
case "ADD":
|
||||
err = cmdAdd(cmdArgs)
|
||||
|
@ -17,7 +17,6 @@ package skel
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
@ -48,7 +47,7 @@ func (c *fakeCmd) Func(args *CmdArgs) error {
|
||||
var _ = Describe("dispatching to the correct callback", func() {
|
||||
var (
|
||||
environment map[string]string
|
||||
stdin io.Reader
|
||||
stdinData string
|
||||
stdout, stderr *bytes.Buffer
|
||||
cmdAdd, cmdDel *fakeCmd
|
||||
dispatch *dispatcher
|
||||
@ -65,13 +64,14 @@ var _ = Describe("dispatching to the correct callback", func() {
|
||||
"CNI_ARGS": "some;extra;args",
|
||||
"CNI_PATH": "/some/cni/path",
|
||||
}
|
||||
stdin = strings.NewReader(`{ "some": "config" }`)
|
||||
|
||||
stdinData = `{ "some": "config", "cniVersion": "9.8.7" }`
|
||||
stdout = &bytes.Buffer{}
|
||||
stderr = &bytes.Buffer{}
|
||||
versionInfo = version.PluginSupports("9.8.7")
|
||||
dispatch = &dispatcher{
|
||||
Getenv: func(key string) string { return environment[key] },
|
||||
Stdin: stdin,
|
||||
Stdin: strings.NewReader(stdinData),
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
}
|
||||
@ -83,7 +83,7 @@ var _ = Describe("dispatching to the correct callback", func() {
|
||||
IfName: "eth0",
|
||||
Args: "some;extra;args",
|
||||
Path: "/some/cni/path",
|
||||
StdinData: []byte(`{ "some": "config" }`),
|
||||
StdinData: []byte(stdinData),
|
||||
}
|
||||
})
|
||||
|
||||
@ -144,6 +144,22 @@ var _ = Describe("dispatching to the correct callback", func() {
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the stdin data is missing the required cniVersion config", func() {
|
||||
BeforeEach(func() {
|
||||
dispatch.Stdin = strings.NewReader(`{ "some": "config" }`)
|
||||
})
|
||||
|
||||
It("immediately returns a useful error", func() {
|
||||
err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo)
|
||||
Expect(err).To(MatchError("missing required config cniVersion"))
|
||||
})
|
||||
|
||||
It("does not call either callback", func() {
|
||||
Expect(cmdAdd.CallCount).To(Equal(0))
|
||||
Expect(cmdDel.CallCount).To(Equal(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the CNI_COMMAND is DEL", func() {
|
||||
|
@ -56,6 +56,7 @@ func PluginSupports(supportedVersions ...string) PluginInfo {
|
||||
}
|
||||
}
|
||||
|
||||
// PluginDecoder can decode the response returned by a plugin's VERSION command
|
||||
type PluginDecoder struct{}
|
||||
|
||||
func (_ *PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user