open-nomad/client/fingerprint/cni.go
2023-04-10 15:36:59 +00:00

89 lines
2.4 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package fingerprint
import (
"fmt"
"os"
"strings"
"github.com/containernetworking/cni/libcni"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/nomad/structs"
)
// CNIFingerprint creates a fingerprint of the CNI configuration(s) on the
// Nomad client.
type CNIFingerprint struct {
StaticFingerprinter
logger hclog.Logger
}
func NewCNIFingerprint(logger hclog.Logger) Fingerprint {
return &CNIFingerprint{logger: logger}
}
func (f *CNIFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error {
confDir := req.Config.CNIConfigDir
networks := map[string]struct{}{}
if _, err := os.Stat(confDir); os.IsNotExist(err) {
f.logger.Debug("CNI config dir is not set or does not exist, skipping", "cni_config_dir", confDir)
resp.Detected = false
return nil
}
files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"})
if err != nil {
return fmt.Errorf("failed to detect CNI conf files: %v", err)
}
for _, confFile := range files {
if strings.HasSuffix(confFile, ".conflist") {
confList, err := libcni.ConfListFromFile(confFile)
if err != nil {
return fmt.Errorf("failed to load CNI config list file %s: %v", confFile, err)
}
if _, ok := networks[confList.Name]; ok {
f.logger.Warn("duplicate CNI config names found, ignoring file", "name", confList.Name, "file", confFile)
continue
}
networks[confList.Name] = struct{}{}
} else {
conf, err := libcni.ConfFromFile(confFile)
if err != nil {
return fmt.Errorf("failed to load CNI config file %s: %v", confFile, err)
}
if _, ok := networks[conf.Network.Name]; ok {
f.logger.Warn("duplicate CNI config names found, ignoring file", "name", conf.Network.Name, "file", confFile)
continue
}
networks[conf.Network.Name] = struct{}{}
}
}
var nodeNetworks structs.Networks
var newNodeNetworks []*structs.NodeNetworkResource
for name := range networks {
mode := fmt.Sprintf("cni/%s", name)
nodeNetworks = append(nodeNetworks, &structs.NetworkResource{
Mode: mode,
})
newNodeNetworks = append(newNodeNetworks, &structs.NodeNetworkResource{
Mode: mode,
})
f.logger.Debug("detected CNI network", "name", name)
}
resp.NodeResources = &structs.NodeResources{
Networks: nodeNetworks,
NodeNetworks: newNodeNetworks,
}
resp.Detected = true
return nil
}
func (f *CNIFingerprint) Reload() {}