api,libcni: add network config list-based plugin chaining
Using a new ".configlist" file format that allows specifying a list of CNI network configurations to run, add new libcni helper functions to call each plugin in the list, injecting the overall name, CNI version, and previous plugin's Result structure into the configuration of the next plugin.
This commit is contained in:
@ -37,13 +37,14 @@ import (
|
||||
|
||||
type NetConf struct {
|
||||
types.NetConf
|
||||
DebugFile string `json:"debugFile"`
|
||||
DebugFile string `json:"debugFile"`
|
||||
PrevResult *types.Result `json:"prevResult,omitempty"`
|
||||
}
|
||||
|
||||
func loadConf(bytes []byte) (*NetConf, error) {
|
||||
n := &NetConf{}
|
||||
if err := json.Unmarshal(bytes, n); err != nil {
|
||||
return nil, fmt.Errorf("failed to load netconf: %v", err)
|
||||
return nil, fmt.Errorf("failed to load netconf: %v %q", err, string(bytes))
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
@ -66,15 +67,15 @@ func parseExtraArgs(args string) (map[string]string, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func getDebugFilePath(stdinData []byte, args string) (string, error) {
|
||||
func getConfig(stdinData []byte, args string) (string, *NetConf, error) {
|
||||
netConf, err := loadConf(stdinData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
extraArgs, err := parseExtraArgs(args)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
debugFilePath, ok := extraArgs["DEBUG"]
|
||||
@ -82,11 +83,11 @@ func getDebugFilePath(stdinData []byte, args string) (string, error) {
|
||||
debugFilePath = netConf.DebugFile
|
||||
}
|
||||
|
||||
return debugFilePath, nil
|
||||
return debugFilePath, netConf, nil
|
||||
}
|
||||
|
||||
func debugBehavior(args *skel.CmdArgs, command string) error {
|
||||
debugFilePath, err := getDebugFilePath(args.StdinData, args.Args)
|
||||
debugFilePath, netConf, err := getConfig(args.StdinData, args.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -118,6 +119,15 @@ func debugBehavior(args *skel.CmdArgs, command string) error {
|
||||
|
||||
if debug.ReportError != "" {
|
||||
return errors.New(debug.ReportError)
|
||||
} else if debug.ReportResult == "PASSTHROUGH" || debug.ReportResult == "INJECT-DNS" {
|
||||
if debug.ReportResult == "INJECT-DNS" {
|
||||
netConf.PrevResult.DNS.Nameservers = []string{"1.2.3.4"}
|
||||
}
|
||||
newResult, err := json.Marshal(netConf.PrevResult)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal new result: %v", err)
|
||||
}
|
||||
os.Stdout.WriteString(string(newResult))
|
||||
} else {
|
||||
os.Stdout.WriteString(debug.ReportResult)
|
||||
}
|
||||
@ -132,7 +142,7 @@ func debugGetSupportedVersions(stdinData []byte) []string {
|
||||
return vers
|
||||
}
|
||||
|
||||
debugFilePath, err := getDebugFilePath(stdinData, cniArgs)
|
||||
debugFilePath, _, err := getConfig(stdinData, cniArgs)
|
||||
if err != nil {
|
||||
panic("test setup error: unable to get debug file path: " + err.Error())
|
||||
}
|
||||
|
@ -96,6 +96,45 @@ var _ = Describe("No-op plugin", func() {
|
||||
Eventually(session).Should(gexec.Exit(2))
|
||||
})
|
||||
|
||||
It("pass previous result through when ReportResult is PASSTHROUGH", func() {
|
||||
debug = &noop_debug.Debug{ReportResult: "PASSTHROUGH"}
|
||||
Expect(debug.WriteDebug(debugFileName)).To(Succeed())
|
||||
|
||||
cmd.Stdin = strings.NewReader(`{
|
||||
"some":"stdin-json",
|
||||
"cniVersion": "0.2.0",
|
||||
"prevResult": {
|
||||
"ip4": {"ip": "10.1.2.15/24"}
|
||||
}
|
||||
}`)
|
||||
session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Eventually(session).Should(gexec.Exit(0))
|
||||
Expect(session.Out.Contents()).To(MatchJSON(`{"ip4": {"ip": "10.1.2.15/24"}, "dns": {}}`))
|
||||
})
|
||||
|
||||
It("injects DNS into previous result when ReportResult is INJECT-DNS", func() {
|
||||
debug = &noop_debug.Debug{ReportResult: "INJECT-DNS"}
|
||||
Expect(debug.WriteDebug(debugFileName)).To(Succeed())
|
||||
|
||||
cmd.Stdin = strings.NewReader(`{
|
||||
"some":"stdin-json",
|
||||
"cniVersion": "0.2.0",
|
||||
"prevResult": {
|
||||
"ip4": {"ip": "10.1.2.3/24"},
|
||||
"dns": {}
|
||||
}
|
||||
}`)
|
||||
|
||||
session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Eventually(session).Should(gexec.Exit(0))
|
||||
Expect(session.Out.Contents()).To(MatchJSON(`{
|
||||
"ip4": {"ip": "10.1.2.3/24"},
|
||||
"dns": {"nameservers": ["1.2.3.4"]}
|
||||
}`))
|
||||
})
|
||||
|
||||
It("allows passing debug file in config JSON", func() {
|
||||
// Remove the DEBUG option from CNI_ARGS and regular args
|
||||
newArgs := "FOO=BAR"
|
||||
|
Reference in New Issue
Block a user