github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/fingerprint/cni.go (about) 1 package fingerprint 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 8 "github.com/containernetworking/cni/libcni" 9 "github.com/hashicorp/go-hclog" 10 "github.com/hashicorp/nomad/nomad/structs" 11 ) 12 13 // CNIFingerprint creates a fingerprint of the CNI configuration(s) on the 14 // Nomad client. 15 type CNIFingerprint struct { 16 StaticFingerprinter 17 logger hclog.Logger 18 } 19 20 func NewCNIFingerprint(logger hclog.Logger) Fingerprint { 21 return &CNIFingerprint{logger: logger} 22 } 23 24 func (f *CNIFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { 25 confDir := req.Config.CNIConfigDir 26 networks := map[string]struct{}{} 27 if _, err := os.Stat(confDir); os.IsNotExist(err) { 28 f.logger.Debug("CNI config dir is not set or does not exist, skipping", "cni_config_dir", confDir) 29 resp.Detected = false 30 return nil 31 } 32 33 files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"}) 34 if err != nil { 35 return fmt.Errorf("failed to detect CNI conf files: %v", err) 36 } 37 38 for _, confFile := range files { 39 if strings.HasSuffix(confFile, ".conflist") { 40 confList, err := libcni.ConfListFromFile(confFile) 41 if err != nil { 42 return fmt.Errorf("failed to load CNI config list file %s: %v", confFile, err) 43 } 44 if _, ok := networks[confList.Name]; ok { 45 f.logger.Warn("duplicate CNI config names found, ignoring file", "name", confList.Name, "file", confFile) 46 continue 47 } 48 networks[confList.Name] = struct{}{} 49 } else { 50 conf, err := libcni.ConfFromFile(confFile) 51 if err != nil { 52 return fmt.Errorf("failed to load CNI config file %s: %v", confFile, err) 53 } 54 if _, ok := networks[conf.Network.Name]; ok { 55 f.logger.Warn("duplicate CNI config names found, ignoring file", "name", conf.Network.Name, "file", confFile) 56 continue 57 } 58 networks[conf.Network.Name] = struct{}{} 59 } 60 } 61 62 var nodeNetworks structs.Networks 63 var newNodeNetworks []*structs.NodeNetworkResource 64 65 for name := range networks { 66 mode := fmt.Sprintf("cni/%s", name) 67 nodeNetworks = append(nodeNetworks, &structs.NetworkResource{ 68 Mode: mode, 69 }) 70 newNodeNetworks = append(newNodeNetworks, &structs.NodeNetworkResource{ 71 Mode: mode, 72 }) 73 f.logger.Debug("detected CNI network", "name", name) 74 } 75 76 resp.NodeResources = &structs.NodeResources{ 77 Networks: nodeNetworks, 78 NodeNetworks: newNodeNetworks, 79 } 80 81 resp.Detected = true 82 return nil 83 } 84 85 func (f *CNIFingerprint) Reload() {}