github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/network/files.go (about) 1 package network 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "sort" 8 "strings" 9 10 "github.com/containernetworking/cni/libcni" 11 "github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator" 12 "github.com/pkg/errors" 13 ) 14 15 // LoadCNIConfsFromDir loads all the CNI configurations from a dir 16 func LoadCNIConfsFromDir(dir string) ([]*libcni.NetworkConfigList, error) { 17 var configs []*libcni.NetworkConfigList 18 files, err := libcni.ConfFiles(dir, []string{".conflist"}) 19 if err != nil { 20 return nil, err 21 } 22 sort.Strings(files) 23 24 for _, confFile := range files { 25 conf, err := libcni.ConfListFromFile(confFile) 26 if err != nil { 27 return nil, errors.Wrapf(err, "in %s", confFile) 28 } 29 configs = append(configs, conf) 30 } 31 return configs, nil 32 } 33 34 // GetCNIConfigPathByName finds a CNI network by name and 35 // returns its configuration file path 36 func GetCNIConfigPathByName(name string) (string, error) { 37 files, err := libcni.ConfFiles(CNIConfigDir, []string{".conflist"}) 38 if err != nil { 39 return "", err 40 } 41 for _, confFile := range files { 42 conf, err := libcni.ConfListFromFile(confFile) 43 if err != nil { 44 return "", errors.Wrapf(err, "in %s", confFile) 45 } 46 if conf.Name == name { 47 return confFile, nil 48 } 49 } 50 return "", errors.Wrap(ErrNetworkNotFound, fmt.Sprintf("unable to find network configuration for %s", name)) 51 } 52 53 // ReadRawCNIConfByName reads the raw CNI configuration for a CNI 54 // network by name 55 func ReadRawCNIConfByName(name string) ([]byte, error) { 56 confFile, err := GetCNIConfigPathByName(name) 57 if err != nil { 58 return nil, err 59 } 60 b, err := ioutil.ReadFile(confFile) 61 return b, err 62 } 63 64 // GetCNIPlugins returns a list of plugins that a given network 65 // has in the form of a string 66 func GetCNIPlugins(list *libcni.NetworkConfigList) string { 67 var plugins []string 68 for _, plug := range list.Plugins { 69 plugins = append(plugins, plug.Network.Type) 70 } 71 return strings.Join(plugins, ",") 72 } 73 74 // GetNetworksFromFilesystem gets all the networks from the cni configuration 75 // files 76 func GetNetworksFromFilesystem() ([]*allocator.Net, error) { 77 var cniNetworks []*allocator.Net 78 networks, err := LoadCNIConfsFromDir(CNIConfigDir) 79 if err != nil { 80 return nil, err 81 } 82 for _, n := range networks { 83 for _, cniplugin := range n.Plugins { 84 if cniplugin.Network.Type == "bridge" { 85 ipamConf := allocator.Net{} 86 if err := json.Unmarshal(cniplugin.Bytes, &ipamConf); err != nil { 87 return nil, err 88 } 89 cniNetworks = append(cniNetworks, &ipamConf) 90 break 91 } 92 } 93 } 94 return cniNetworks, nil 95 } 96 97 // GetNetworkNamesFromFileSystem gets all the names from the cni network 98 // configuration files 99 func GetNetworkNamesFromFileSystem() ([]string, error) { 100 var networkNames []string 101 networks, err := LoadCNIConfsFromDir(CNIConfigDir) 102 if err != nil { 103 return nil, err 104 } 105 for _, n := range networks { 106 networkNames = append(networkNames, n.Name) 107 } 108 return networkNames, nil 109 } 110 111 // GetInterfaceNameFromConfig returns the interface name for the bridge plugin 112 func GetInterfaceNameFromConfig(path string) (string, error) { 113 var name string 114 conf, err := libcni.ConfListFromFile(path) 115 if err != nil { 116 return "", err 117 } 118 for _, cniplugin := range conf.Plugins { 119 if cniplugin.Network.Type == "bridge" { 120 plugin := make(map[string]interface{}) 121 if err := json.Unmarshal(cniplugin.Bytes, &plugin); err != nil { 122 return "", err 123 } 124 name = plugin["bridge"].(string) 125 break 126 } 127 } 128 if len(name) == 0 { 129 return "", errors.New("unable to find interface name for network") 130 } 131 return name, nil 132 } 133 134 // GetBridgeNamesFromFileSystem is a convenience function to get all the bridge 135 // names from the configured networks 136 func GetBridgeNamesFromFileSystem() ([]string, error) { 137 var bridgeNames []string 138 networks, err := LoadCNIConfsFromDir(CNIConfigDir) 139 if err != nil { 140 return nil, err 141 } 142 for _, n := range networks { 143 var name string 144 // iterate network conflists 145 for _, cniplugin := range n.Plugins { 146 // iterate plugins 147 if cniplugin.Network.Type == "bridge" { 148 plugin := make(map[string]interface{}) 149 if err := json.Unmarshal(cniplugin.Bytes, &plugin); err != nil { 150 continue 151 } 152 name = plugin["bridge"].(string) 153 } 154 } 155 bridgeNames = append(bridgeNames, name) 156 } 157 return bridgeNames, nil 158 }