Pārlūkot izejas kodu

Merge pull request #754 from mgleung/iface-regex

Added iface-regex option
Tom Denham 7 gadi atpakaļ
vecāks
revīzija
768cae01c4
2 mainītis faili ar 49 papildinājumiem un 2 dzēšanām
  1. 1 0
      Documentation/configuration.md
  2. 48 2
      main.go

+ 1 - 0
Documentation/configuration.md

@@ -54,6 +54,7 @@ The following configuration illustrates the use of most options with `udp` backe
 --etcd-cafile="": SSL Certificate Authority file used to secure etcd communication.
 --kube-subnet-mgr: Contact the Kubernetes API for subnet assignment instead of etcd.
 --iface="": interface to use (IP or name) for inter-host communication. Defaults to the interface for the default route on the machine.
+--iface-regex="": regex expression to match the first interface to use (IP or name) for inter-host communication. If unspecified, will default to the interface for the default route on the machine. This option is superseded by the iface option and will not be used if the iface option is also specified.
 --subnet-file=/run/flannel/subnet.env: filename where env variables (subnet and MTU values) will be written to.
 --subnet-lease-renew-margin=60: subnet lease renewal margin, in minutes.
 --ip-masq=false: setup IP masquerade for traffic destined for outside the flannel network. Flannel assumes that the default policy is ACCEPT in the NAT POSTROUTING chain.

+ 48 - 2
main.go

@@ -23,6 +23,7 @@ import (
 	"os"
 	"os/signal"
 	"path/filepath"
+	"regexp"
 	"strconv"
 	"strings"
 	"syscall"
@@ -65,6 +66,7 @@ type CmdLineOpts struct {
 	version                bool
 	kubeSubnetMgr          bool
 	iface                  string
+	ifaceRegex             string
 	ipMasq                 bool
 	subnetFile             string
 	subnetDir              string
@@ -89,6 +91,7 @@ func init() {
 	flag.StringVar(&opts.etcdUsername, "etcd-username", "", "Username for BasicAuth to etcd")
 	flag.StringVar(&opts.etcdPassword, "etcd-password", "", "Password for BasicAuth to etcd")
 	flag.StringVar(&opts.iface, "iface", "", "interface to use (IP or name) for inter-host communication")
+	flag.StringVar(&opts.ifaceRegex, "iface-regex", "", "regex expression to match the first interface to use (IP or name) for inter-host communication. Skipped if the iface option is also specified")
 	flag.StringVar(&opts.subnetFile, "subnet-file", "/run/flannel/subnet.env", "filename where env variables (subnet, MTU, ... ) will be written to")
 	flag.StringVar(&opts.publicIP, "public-ip", "", "IP accessible by other nodes for inter-host communication")
 	flag.IntVar(&opts.subnetLeaseRenewMargin, "subnet-lease-renew-margin", 60, "Subnet lease renewal margin, in minutes.")
@@ -140,7 +143,7 @@ func main() {
 	flagutil.SetFlagsFromEnv(flag.CommandLine, "FLANNELD")
 
 	// Work out which interface to use
-	extIface, err := LookupExtIface(opts.iface)
+	extIface, err := LookupExtIface(opts.iface, opts.ifaceRegex)
 	if err != nil {
 		log.Error("Failed to find interface to use: ", err)
 		os.Exit(1)
@@ -306,7 +309,7 @@ func MonitorLease(ctx context.Context, sm subnet.Manager, bn backend.Network) er
 	}
 }
 
-func LookupExtIface(ifname string) (*backend.ExternalInterface, error) {
+func LookupExtIface(ifname string, ifregex string) (*backend.ExternalInterface, error) {
 	var iface *net.Interface
 	var ifaceAddr net.IP
 	var err error
@@ -324,6 +327,49 @@ func LookupExtIface(ifname string) (*backend.ExternalInterface, error) {
 				return nil, fmt.Errorf("error looking up interface %s: %s", ifname, err)
 			}
 		}
+	} else if len(ifregex) > 0 {
+		// Use the regex if specified and the iface option for matching a specific ip or name is not used
+		ifaces, err := net.Interfaces()
+		if err != nil {
+			return nil, fmt.Errorf("error listing all interfaces: %s", err)
+		}
+
+		// Check IP
+		for _, ifaceToMatch := range ifaces {
+			ifaceIP, err := ip.GetIfaceIP4Addr(&ifaceToMatch)
+			if err != nil {
+				// Skip if there is no IPv4 address
+				continue
+			}
+
+			matched, err := regexp.MatchString(ifregex, ifaceIP.String())
+			if err != nil {
+				return nil, fmt.Errorf("regex error matching pattern %s to %s", ifregex, ifaceIP.String())
+			}
+
+			if matched {
+				ifaceAddr = ifaceIP
+				iface = &ifaceToMatch
+				break
+			}
+		}
+
+		// Check Name
+		if iface == nil && ifaceAddr == nil {
+			for _, ifaceToMatch := range ifaces {
+				matched, err := regexp.MatchString(ifregex, ifaceToMatch.Name)
+				if err != nil {
+					return nil, fmt.Errorf("regex error matching pattern %s to %s", ifregex, ifaceToMatch.Name)
+				}
+
+				if matched {
+					iface = &ifaceToMatch
+					break
+				}
+			}
+		}
+
+		return nil, fmt.Errorf("Could not match pattern %s to any of the available network interfaces", ifregex)
 	} else {
 		log.Info("Determining IP address of default interface")
 		if iface, err = ip.GetDefaultGatewayIface(); err != nil {