cni: handle multi-path cni_path when fingerprinting plugins (#16163)
This PR fixes the CNI plugin fingerprinter to take into account the fact that the cni_path config can be a multi-path (e.g. `/foo:/bar:/baz`). Accumulate plugins from each of the possible path elements. If scanning any of the named directory fails, the fingerprinter fails. Fixes #16083 No CL/BP - has not shipped yet.
This commit is contained in:
parent
1f7f96cf38
commit
490c902c62
|
@ -40,24 +40,28 @@ func (f *PluginsCNIFingerprint) Fingerprint(req *FingerprintRequest, resp *Finge
|
|||
return nil
|
||||
}
|
||||
|
||||
// list the cni_path directory
|
||||
entries, err := f.lister(cniPath)
|
||||
switch {
|
||||
case err != nil:
|
||||
f.logger.Warn("failed to read CNI plugins directory", "cni_path", cniPath, "error", err)
|
||||
resp.Detected = false
|
||||
return nil
|
||||
case len(entries) == 0:
|
||||
f.logger.Debug("no CNI plugins found", "cni_path", cniPath)
|
||||
resp.Detected = true
|
||||
return nil
|
||||
}
|
||||
// cniPath could be a multi-path, e.g. /opt/cni/bin:/custom/cni/bin
|
||||
cniPathList := filepath.SplitList(cniPath)
|
||||
for _, cniPath = range cniPathList {
|
||||
// list the cni_path directory
|
||||
entries, err := f.lister(cniPath)
|
||||
switch {
|
||||
case err != nil:
|
||||
f.logger.Warn("failed to read CNI plugins directory", "cni_path", cniPath, "error", err)
|
||||
resp.Detected = false
|
||||
return nil
|
||||
case len(entries) == 0:
|
||||
f.logger.Debug("no CNI plugins found", "cni_path", cniPath)
|
||||
resp.Detected = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// for each file in cni_path, detect executables and try to get their version
|
||||
for _, entry := range entries {
|
||||
v, ok := f.detectOne(cniPath, entry)
|
||||
if ok {
|
||||
resp.AddAttribute(f.attribute(entry.Name()), v)
|
||||
// for each file in cni_path, detect executables and try to get their version
|
||||
for _, entry := range entries {
|
||||
v, ok := f.detectOnePlugin(cniPath, entry)
|
||||
if ok {
|
||||
resp.AddAttribute(f.attribute(entry.Name()), v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +74,7 @@ func (f *PluginsCNIFingerprint) attribute(filename string) string {
|
|||
return fmt.Sprintf("%s.%s", cniPluginAttribute, filename)
|
||||
}
|
||||
|
||||
func (f *PluginsCNIFingerprint) detectOne(cniPath string, entry os.DirEntry) (string, bool) {
|
||||
func (f *PluginsCNIFingerprint) detectOnePlugin(pluginPath string, entry os.DirEntry) (string, bool) {
|
||||
fi, err := entry.Info()
|
||||
if err != nil {
|
||||
f.logger.Debug("failed to read cni directory entry", "error", err)
|
||||
|
@ -82,7 +86,7 @@ func (f *PluginsCNIFingerprint) detectOne(cniPath string, entry os.DirEntry) (st
|
|||
return "", false // not executable
|
||||
}
|
||||
|
||||
exePath := filepath.Join(cniPath, fi.Name())
|
||||
exePath := filepath.Join(pluginPath, fi.Name())
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
|
|
|
@ -30,6 +30,28 @@ func TestPluginsCNIFingerprint_Fingerprint_present(t *testing.T) {
|
|||
must.Eq(t, "v1.0.2", response.Attributes[attrBridge])
|
||||
}
|
||||
|
||||
func TestPluginsCNIFingerprint_Fingerprint_multi(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
|
||||
f := NewPluginsCNIFingerprint(testlog.HCLogger(t))
|
||||
request := &FingerprintRequest{
|
||||
Config: &config.Config{
|
||||
CNIPath: "./test_fixtures/cni:./test_fixtures/cni2",
|
||||
},
|
||||
}
|
||||
response := new(FingerprintResponse)
|
||||
|
||||
err := f.Fingerprint(request, response)
|
||||
must.NoError(t, err)
|
||||
must.True(t, response.Detected)
|
||||
attrCustom := f.(*PluginsCNIFingerprint).attribute("custom")
|
||||
attrBridge := f.(*PluginsCNIFingerprint).attribute("bridge")
|
||||
attrCustom2 := f.(*PluginsCNIFingerprint).attribute("custom2")
|
||||
must.Eq(t, "v1.2.3", response.Attributes[attrCustom])
|
||||
must.Eq(t, "v1.0.2", response.Attributes[attrBridge])
|
||||
must.Eq(t, "v9.9.9", response.Attributes[attrCustom2])
|
||||
}
|
||||
|
||||
func TestPluginsCNIFingerprint_Fingerprint_absent(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "Custom v9.9.9 Plugin"
|
Loading…
Reference in New Issue