github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/domain/infra/abi/network.go (about)

     1  package abi
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/containernetworking/cni/libcni"
     9  	"github.com/containers/podman/v2/libpod/define"
    10  	"github.com/containers/podman/v2/libpod/network"
    11  	"github.com/containers/podman/v2/pkg/domain/entities"
    12  	"github.com/containers/podman/v2/pkg/util"
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
    17  	var reports []*entities.NetworkListReport
    18  
    19  	config, err := ic.Libpod.GetConfig()
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  
    24  	networks, err := network.LoadCNIConfsFromDir(network.GetCNIConfDir(config))
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  
    29  	var tokens []string
    30  	// tokenize the networkListOptions.Filter in key=value.
    31  	if len(options.Filter) > 0 {
    32  		tokens = strings.Split(options.Filter, "=")
    33  		if len(tokens) != 2 {
    34  			return nil, fmt.Errorf("invalid filter syntax : %s", options.Filter)
    35  		}
    36  	}
    37  
    38  	for _, n := range networks {
    39  		if ifPassesFilterTest(n, tokens) {
    40  			reports = append(reports, &entities.NetworkListReport{NetworkConfigList: n})
    41  		}
    42  	}
    43  	return reports, nil
    44  }
    45  
    46  func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]entities.NetworkInspectReport, []error, error) {
    47  	config, err := ic.Libpod.GetConfig()
    48  	if err != nil {
    49  		return nil, nil, err
    50  	}
    51  	var errs []error
    52  	rawCNINetworks := make([]entities.NetworkInspectReport, 0, len(namesOrIds))
    53  	for _, name := range namesOrIds {
    54  		rawList, err := network.InspectNetwork(config, name)
    55  		if err != nil {
    56  			if errors.Cause(err) == define.ErrNoSuchNetwork {
    57  				errs = append(errs, errors.Errorf("no such network %s", name))
    58  				continue
    59  			} else {
    60  				return nil, nil, errors.Wrapf(err, "error inspecting network %s", name)
    61  			}
    62  		}
    63  		rawCNINetworks = append(rawCNINetworks, rawList)
    64  	}
    65  	return rawCNINetworks, errs, nil
    66  }
    67  
    68  func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) {
    69  	reports := []*entities.NetworkRmReport{}
    70  
    71  	config, err := ic.Libpod.GetConfig()
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	for _, name := range namesOrIds {
    77  		report := entities.NetworkRmReport{Name: name}
    78  		containers, err := ic.Libpod.GetAllContainers()
    79  		if err != nil {
    80  			return reports, err
    81  		}
    82  		// We need to iterate containers looking to see if they belong to the given network
    83  		for _, c := range containers {
    84  			if util.StringInSlice(name, c.Config().Networks) {
    85  				// if user passes force, we nuke containers and pods
    86  				if !options.Force {
    87  					// Without the force option, we return an error
    88  					return reports, errors.Wrapf(define.ErrNetworkInUse, "%q has associated containers with it. Use -f to forcibly delete containers and pods", name)
    89  				}
    90  				if c.IsInfra() {
    91  					// if we have a infra container we need to remove the pod
    92  					pod, err := ic.Libpod.GetPod(c.PodID())
    93  					if err != nil {
    94  						return reports, err
    95  					}
    96  					if err := ic.Libpod.RemovePod(ctx, pod, true, true); err != nil {
    97  						return reports, err
    98  					}
    99  				} else if err := ic.Libpod.RemoveContainer(ctx, c, true, true); err != nil && errors.Cause(err) != define.ErrNoSuchCtr {
   100  					return reports, err
   101  				}
   102  			}
   103  		}
   104  		if err := network.RemoveNetwork(config, name); err != nil {
   105  			report.Err = err
   106  		}
   107  		reports = append(reports, &report)
   108  	}
   109  	return reports, nil
   110  }
   111  
   112  func (ic *ContainerEngine) NetworkCreate(ctx context.Context, name string, options entities.NetworkCreateOptions) (*entities.NetworkCreateReport, error) {
   113  	runtimeConfig, err := ic.Libpod.GetConfig()
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  	return network.Create(name, options, runtimeConfig)
   118  }
   119  
   120  func ifPassesFilterTest(netconf *libcni.NetworkConfigList, filter []string) bool {
   121  	result := false
   122  	if len(filter) == 0 {
   123  		// No filter, so pass
   124  		return true
   125  	}
   126  	switch strings.ToLower(filter[0]) {
   127  	case "name":
   128  		if filter[1] == netconf.Name {
   129  			result = true
   130  		}
   131  	case "plugin":
   132  		plugins := network.GetCNIPlugins(netconf)
   133  		if strings.Contains(plugins, filter[1]) {
   134  			result = true
   135  		}
   136  	default:
   137  		result = false
   138  	}
   139  	return result
   140  }
   141  
   142  // NetworkDisconnect removes a container from a given network
   143  func (ic *ContainerEngine) NetworkDisconnect(ctx context.Context, networkname string, options entities.NetworkDisconnectOptions) error {
   144  	return ic.Libpod.DisconnectContainerFromNetwork(options.Container, networkname, options.Force)
   145  }
   146  
   147  func (ic *ContainerEngine) NetworkConnect(ctx context.Context, networkname string, options entities.NetworkConnectOptions) error {
   148  	return ic.Libpod.ConnectContainerToNetwork(options.Container, networkname, options.Aliases)
   149  }