summaryrefslogtreecommitdiff
path: root/pkg/adapter/network.go
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2019-08-08 06:01:00 -0500
committerbaude <bbaude@redhat.com>2019-09-09 09:32:43 -0500
commitee432cf2792c5dbe81953007f1fd5c87beb3ebd5 (patch)
treedc0646e4b2faeadf9cca58bf80f1e90d98c50165 /pkg/adapter/network.go
parent30cbb0091515a7f802f0f3f3ee486be6ff98f645 (diff)
downloadpodman-ee432cf2792c5dbe81953007f1fd5c87beb3ebd5.tar.gz
podman-ee432cf2792c5dbe81953007f1fd5c87beb3ebd5.tar.bz2
podman-ee432cf2792c5dbe81953007f1fd5c87beb3ebd5.zip
podman network create
initial implementation of network create. we only support bridging networks with this first pass. Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/adapter/network.go')
-rw-r--r--pkg/adapter/network.go135
1 files changed, 97 insertions, 38 deletions
diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go
index cf3a1dfdd..e4a160767 100644
--- a/pkg/adapter/network.go
+++ b/pkg/adapter/network.go
@@ -5,12 +5,13 @@ package adapter
import (
"encoding/json"
"fmt"
+ "github.com/containers/libpod/pkg/util"
"io/ioutil"
"os"
- "strings"
+ "path/filepath"
"text/tabwriter"
- "github.com/containernetworking/cni/libcni"
+ cniversion "github.com/containernetworking/cni/pkg/version"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/network"
"github.com/pkg/errors"
@@ -51,7 +52,7 @@ func (r *LocalRuntime) NetworkList(cli *cliconfig.NetworkListValues) error {
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 {
+ if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", cniNetwork.Name, cniNetwork.CNIVersion, network.GetCNIPlugins(cniNetwork)); err != nil {
return err
}
}
@@ -64,12 +65,8 @@ 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)
+ b, err := network.ReadRawCNIConfByName(name)
if err != nil {
return err
}
@@ -89,12 +86,8 @@ func (r *LocalRuntime) NetworkInspect(cli *cliconfig.NetworkInspectValues) error
// 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)
+ cniPath, err := network.GetCNIConfigPathByName(name)
if err != nil {
return err
}
@@ -106,42 +99,108 @@ func (r *LocalRuntime) NetworkRemove(cli *cliconfig.NetworkRmValues) error {
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"})
+// NetworkCreate creates a CNI network
+func (r *LocalRuntime) NetworkCreate(cli *cliconfig.NetworkCreateValues) (string, error) {
+ var (
+ err error
+ )
+
+ isGateway := true
+ ipMasq := true
+ subnet := &cli.Network
+ ipRange := cli.IPRange
+
+ // if range is provided, make sure it is "in" network
+ if cli.IsSet("subnet") {
+ // if network is provided, does it conflict with existing CNI or live networks
+ err = network.ValidateUserNetworkIsAvailable(subnet)
+ } else {
+ // if no network is provided, figure out network
+ subnet, err = network.GetFreeNetwork()
+ }
if err != nil {
return "", err
}
- for _, confFile := range files {
- conf, err := libcni.ConfListFromFile(confFile)
+
+ gateway := cli.Gateway
+ if gateway == nil {
+ // if no gateway is provided, provide it as first ip of network
+ gateway = network.CalcGatewayIP(subnet)
+ }
+ // if network is provided and if gateway is provided, make sure it is "in" network
+ if cli.IsSet("subnet") && cli.IsSet("gateway") {
+ if !subnet.Contains(gateway) {
+ return "", errors.Errorf("gateway %s is not in valid for subnet %s", gateway.String(), subnet.String())
+ }
+ }
+ if cli.Internal {
+ isGateway = false
+ ipMasq = false
+ }
+
+ // if a range is given, we need to ensure it is "in" the network range.
+ if cli.IsSet("ip-range") {
+ if !cli.IsSet("subnet") {
+ return "", errors.New("you must define a subnet range to define an ip-range")
+ }
+ firstIP, err := network.FirstIPInSubnet(&cli.IPRange)
+ if err != nil {
+ return "", err
+ }
+ lastIP, err := network.LastIPInSubnet(&cli.IPRange)
if err != nil {
return "", err
}
- if conf.Name == name {
- return confFile, nil
+ if !subnet.Contains(firstIP) || !subnet.Contains(lastIP) {
+ return "", errors.Errorf("the ip range %s does not fall within the subnet range %s", cli.IPRange.String(), subnet.String())
+ }
+ }
+ bridgeDeviceName, err := network.GetFreeDeviceName()
+ if err != nil {
+ return "", err
+ }
+ // If no name is given, we give the name of the bridge device
+ name := bridgeDeviceName
+ if len(cli.InputArgs) > 0 {
+ name = cli.InputArgs[0]
+ netNames, err := network.GetNetworkNamesFromFileSystem()
+ if err != nil {
+ return "", err
+ }
+ if util.StringInSlice(name, netNames) {
+ return "", errors.Errorf("the network name %s is already used", name)
}
}
- 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)
+ ncList := network.NewNcList(name, cniversion.Current())
+ var plugins []network.CNIPlugins
+ var routes []network.IPAMRoute
+
+ defaultRoute, err := network.NewIPAMDefaultRoute()
if err != nil {
- return nil, err
+ return "", err
+ }
+ routes = append(routes, defaultRoute)
+ ipamConfig, err := network.NewIPAMHostLocalConf(subnet, routes, ipRange, gateway)
+ if err != nil {
+ return "", 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)
+ // TODO need to iron out the role of isDefaultGW and IPMasq
+ bridge := network.NewHostLocalBridge(bridgeDeviceName, isGateway, false, ipMasq, ipamConfig)
+ plugins = append(plugins, bridge)
+ plugins = append(plugins, network.NewPortMapPlugin())
+ plugins = append(plugins, network.NewFirewallPlugin())
+ ncList["plugins"] = plugins
+ b, err := json.MarshalIndent(ncList, "", " ")
+ if err != nil {
+ return "", err
+ }
+ cniConfigPath, err := getCNIConfDir(r)
+ if err != nil {
+ return "", err
}
- return strings.Join(plugins, ",")
+ cniPathName := filepath.Join(cniConfigPath, fmt.Sprintf("%s.conflist", name))
+ err = ioutil.WriteFile(cniPathName, b, 0644)
+ return cniPathName, err
}