Files
podman/pkg/adapter/network.go
baude 6220ef1488 inclusion of podman network
adding podman network and the subcommands inspect, list, and rm.  the
inspect subcommand displays the raw cni network configuration.  the list
subcommand displays a summary of the cni networks ala ps.  and the rm
subcommand removes a cni network.

Signed-off-by: baude <bbaude@redhat.com>
2019-08-15 12:49:12 -05:00

148 lines
3.7 KiB
Go

// +build !remoteclient
package adapter
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"text/tabwriter"
"github.com/containernetworking/cni/libcni"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/network"
"github.com/pkg/errors"
)
func getCNIConfDir(r *LocalRuntime) (string, error) {
config, err := r.GetConfig()
if err != nil {
return "", err
}
configPath := config.CNIConfigDir
if len(config.CNIConfigDir) < 1 {
configPath = network.CNIConfigDir
}
return configPath, nil
}
// NetworkList displays summary information about CNI networks
func (r *LocalRuntime) NetworkList(cli *cliconfig.NetworkListValues) error {
cniConfigPath, err := getCNIConfDir(r)
if err != nil {
return err
}
networks, err := network.LoadCNIConfsFromDir(cniConfigPath)
if err != nil {
return err
}
// quiet means we only print the network names
if cli.Quiet {
for _, cniNetwork := range networks {
fmt.Println(cniNetwork.Name)
}
return nil
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
if _, err := fmt.Fprintln(w, "NAME\tVERSION\tPLUGINS"); err != nil {
return err
}
for _, cniNetwork := range networks {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", cniNetwork.Name, cniNetwork.CNIVersion, getCNIPlugins(cniNetwork)); err != nil {
return err
}
}
return w.Flush()
}
// NetworkInspect displays the raw CNI configuration for one
// or more CNI networks
func (r *LocalRuntime) NetworkInspect(cli *cliconfig.NetworkInspectValues) error {
var (
rawCNINetworks []map[string]interface{}
)
cniConfigPath, err := getCNIConfDir(r)
if err != nil {
return err
}
for _, name := range cli.InputArgs {
b, err := readRawCNIConfByName(name, cniConfigPath)
if err != nil {
return err
}
rawList := make(map[string]interface{})
if err := json.Unmarshal(b, &rawList); err != nil {
return fmt.Errorf("error parsing configuration list: %s", err)
}
rawCNINetworks = append(rawCNINetworks, rawList)
}
out, err := json.MarshalIndent(rawCNINetworks, "", "\t")
if err != nil {
return err
}
fmt.Printf("%s\n", out)
return nil
}
// NetworkRemove deletes one or more CNI networks
func (r *LocalRuntime) NetworkRemove(cli *cliconfig.NetworkRmValues) error {
cniConfigPath, err := getCNIConfDir(r)
if err != nil {
return err
}
for _, name := range cli.InputArgs {
cniPath, err := getCNIConfigPathByName(name, cniConfigPath)
if err != nil {
return err
}
if err := os.Remove(cniPath); err != nil {
return err
}
fmt.Printf("Deleted: %s\n", name)
}
return nil
}
// getCNIConfigPathByName finds a CNI network by name and
// returns its configuration file path
func getCNIConfigPathByName(name, cniConfigPath string) (string, error) {
files, err := libcni.ConfFiles(cniConfigPath, []string{".conflist"})
if err != nil {
return "", err
}
for _, confFile := range files {
conf, err := libcni.ConfListFromFile(confFile)
if err != nil {
return "", err
}
if conf.Name == name {
return confFile, nil
}
}
return "", errors.Errorf("unable to find network configuration for %s", name)
}
// readRawCNIConfByName reads the raw CNI configuration for a CNI
// network by name
func readRawCNIConfByName(name, cniConfigPath string) ([]byte, error) {
confFile, err := getCNIConfigPathByName(name, cniConfigPath)
if err != nil {
return nil, err
}
b, err := ioutil.ReadFile(confFile)
return b, err
}
// getCNIPlugins returns a list of plugins that a given network
// has in the form of a string
func getCNIPlugins(list *libcni.NetworkConfigList) string {
var plugins []string
for _, plug := range list.Plugins {
plugins = append(plugins, plug.Network.Type)
}
return strings.Join(plugins, ",")
}