diff --git a/cmd/cloudinit/cloudinit.go b/cmd/cloudinit/cloudinit.go index 560457e2..e3322462 100644 --- a/cmd/cloudinit/cloudinit.go +++ b/cmd/cloudinit/cloudinit.go @@ -38,8 +38,8 @@ import ( "github.com/coreos/coreos-cloudinit/initialize" "github.com/coreos/coreos-cloudinit/pkg" "github.com/coreos/coreos-cloudinit/system" + "github.com/rancher/netconf" "github.com/rancherio/os/cmd/cloudinit/hostname" - rancherNetwork "github.com/rancherio/os/cmd/network" rancherConfig "github.com/rancherio/os/config" "github.com/rancherio/os/util" ) @@ -402,8 +402,8 @@ func getDatasources(cfg *rancherConfig.CloudConfig) []datasource.Datasource { } func enableDoLinkLocal() { - err := rancherNetwork.ApplyNetworkConfigs(&rancherConfig.NetworkConfig{ - Interfaces: map[string]rancherConfig.InterfaceConfig{ + err := netconf.ApplyNetworkConfigs(&netconf.NetworkConfig{ + Interfaces: map[string]netconf.InterfaceConfig{ "eth0": { IPV4LL: true, }, diff --git a/cmd/network/ipv4ll.go b/cmd/network/ipv4ll.go deleted file mode 100644 index 301fd353..00000000 --- a/cmd/network/ipv4ll.go +++ /dev/null @@ -1,75 +0,0 @@ -package network - -import ( - "encoding/binary" - "fmt" - "math/rand" - "net" - - log "github.com/Sirupsen/logrus" - - "github.com/j-keck/arping" - "github.com/vishvananda/netlink" -) - -func AssignLinkLocalIP(link netlink.Link) error { - ifaceName := link.Attrs().Name - iface, err := net.InterfaceByName(ifaceName) - if err != nil { - log.Error("could not get information about interface") - return err - } - addrs, err := iface.Addrs() - if err != nil { - log.Error("Error fetching existing ip on interface") - } - for _, addr := range addrs { - if addr.String()[:7] == "169.254" { - log.Info("Link Local IP already set on interface") - return nil - } - } - randSource, err := getPseudoRandomGenerator(link.Attrs().HardwareAddr) - if err != nil { - return err - } - // try a random address upto 10 times - for i := 0; i < 10; i++ { - randGenerator := rand.New(*randSource) - randomNum := randGenerator.Uint32() - dstIP := getNewIPV4LLAddr(randomNum) - if dstIP[2] == 0 || dstIP[2] == 255 { - i-- - continue - } - _, _, err := arping.PingOverIfaceByName(dstIP, ifaceName) - if err != nil { - // this ip is not being used - addr, err := netlink.ParseAddr(dstIP.String() + "/16") - if err != nil { - log.Errorf("error while parsing ipv4ll addr, err = %v", err) - return err - } - if err := netlink.AddrAdd(link, addr); err != nil { - log.Error("ipv4ll addr add failed") - return err - } - log.Infof("Set %s on %s", dstIP.String(), link.Attrs().Name) - return nil - } - } - log.Error("Could not find a suitable ipv4ll") - return fmt.Errorf("Could not find a suitable ipv4ll") -} - -func getNewIPV4LLAddr(randomNum uint32) net.IP { - byte1 := randomNum & 255 // use least significant 8 bits - byte2 := randomNum >> 24 // use most significant 8 bits - return []byte{169, 254, byte(byte1), byte(byte2)} -} - -func getPseudoRandomGenerator(haAddr []byte) (*rand.Source, error) { - seed, _ := binary.Varint(haAddr) - src := rand.NewSource(seed) - return &src, nil -} diff --git a/cmd/network/network.go b/cmd/network/network.go index 36f15765..04e9505c 100644 --- a/cmd/network/network.go +++ b/cmd/network/network.go @@ -1,20 +1,13 @@ package network import ( - "bytes" - "errors" "fmt" - "net" "os" - "os/exec" - "strings" log "github.com/Sirupsen/logrus" + "github.com/rancher/netconf" "github.com/rancherio/os/config" - "github.com/rancherio/os/docker" - "github.com/ryanuber/go-glob" - "github.com/vishvananda/netlink" ) func Main() { @@ -27,153 +20,7 @@ func Main() { if err != nil { log.Fatal(err) } - ApplyNetworkConfigs(&cfg.Rancher.Network) -} - -func createInterfaces(netCfg *config.NetworkConfig) error { - for name, iface := range netCfg.Interfaces { - if !iface.Bridge { - continue - } - - bridge := netlink.Bridge{} - bridge.LinkAttrs.Name = name - - if err := netlink.LinkAdd(&bridge); err != nil { - log.Errorf("Failed to create bridge %s: %v", name, err) - } - } - - return nil -} - -func ApplyNetworkConfigs(netCfg *config.NetworkConfig) error { - if err := createInterfaces(netCfg); err != nil { - return err - } - - links, err := netlink.LinkList() - if err != nil { - return err - } - - //apply network config - for _, link := range links { - linkName := link.Attrs().Name - var match config.InterfaceConfig - - for key, netConf := range netCfg.Interfaces { - if netConf.Match == "" { - netConf.Match = key - } - - if netConf.Match == "" { - continue - } - - if len(netConf.Match) > 4 && strings.ToLower(netConf.Match[:3]) == "mac" { - haAddr, err := net.ParseMAC(netConf.Match[4:]) - if err != nil { - return err - } - if bytes.Compare(haAddr, link.Attrs().HardwareAddr) == 0 { - // MAC address match is used over all other matches - match = netConf - break - } - } - - // "" means match has not been found - if match.Match == "" && matches(linkName, netConf.Match) { - match = netConf - } - - if netConf.Match == linkName { - // Found exact match, use it over wildcard match - match = netConf - } - } - - if match.Match != "" { - err = applyNetConf(link, match) - if err != nil { - log.Errorf("Failed to apply settings to %s : %v", linkName, err) - } - } - } - - if err != nil { - return err - } - - //post run - if netCfg.PostRun != nil { - return docker.StartAndWait(config.DOCKER_SYSTEM_HOST, netCfg.PostRun) - } - return nil -} - -func applyNetConf(link netlink.Link, netConf config.InterfaceConfig) error { - if netConf.DHCP { - log.Infof("Running DHCP on %s", link.Attrs().Name) - cmd := exec.Command("dhcpcd", "-A4", "-e", "force_hostname=true", link.Attrs().Name) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - log.Error(err) - } - } else if netConf.IPV4LL { - if err := AssignLinkLocalIP(link); err != nil { - log.Error("IPV4LL set failed") - return err - } - } else if netConf.Address == "" { - return nil - } else { - addr, err := netlink.ParseAddr(netConf.Address) - if err != nil { - return err - } - if err := netlink.AddrAdd(link, addr); err != nil { - log.Error("addr add failed") - return err - } - log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name) - } - - if netConf.MTU > 0 { - if err := netlink.LinkSetMTU(link, netConf.MTU); err != nil { - log.Error("set MTU Failed") - return err - } - } - - if err := netlink.LinkSetUp(link); err != nil { - log.Error("failed to setup link") - return err - } - - if netConf.Gateway != "" { - gatewayIp := net.ParseIP(netConf.Gateway) - if gatewayIp == nil { - return errors.New("Invalid gateway address " + netConf.Gateway) - } - - route := netlink.Route{ - Scope: netlink.SCOPE_UNIVERSE, - Gw: net.ParseIP(netConf.Gateway), - } - if err := netlink.RouteAdd(&route); err != nil { - log.Error("gateway set failed") - return err - } - - log.Infof("Set default gateway %s", netConf.Gateway) - } - - return nil -} - -func matches(link, conf string) bool { - return glob.Glob(conf, link) + if err := netconf.ApplyNetworkConfigs(&cfg.Rancher.Network); err != nil { + log.Fatal(err) + } } diff --git a/config/types.go b/config/types.go index 226468dc..29445ecb 100644 --- a/config/types.go +++ b/config/types.go @@ -2,6 +2,7 @@ package config import ( "github.com/coreos/coreos-cloudinit/config" + "github.com/rancher/netconf" "github.com/rancherio/rancher-compose/librcompose/project" ) @@ -76,7 +77,7 @@ type RancherConfig struct { Disable []string `yaml:"disable,omitempty"` ServicesInclude map[string]bool `yaml:"services_include,omitempty"` Modules []string `yaml:"modules,omitempty"` - Network NetworkConfig `yaml:"network,omitempty"` + Network netconf.NetworkConfig `yaml:"network,omitempty"` Repositories Repositories `yaml:"repositories,omitempty"` Ssh SshConfig `yaml:"ssh,omitempty"` State StateConfig `yaml:"state,omitempty"` @@ -97,28 +98,6 @@ type UpgradeConfig struct { Rollback string `yaml:"rollback,omitempty"` } -type DnsConfig struct { - Nameservers []string `yaml:"nameservers,flow,omitempty"` - Search []string `yaml:"search,flow,omitempty"` - Domain string `yaml:"domain,omitempty"` -} - -type NetworkConfig struct { - Dns DnsConfig `yaml:"dns,omitempty"` - Interfaces map[string]InterfaceConfig `yaml:"interfaces,omitempty"` - PostRun *ContainerConfig `yaml:"post_run,omitempty"` -} - -type InterfaceConfig struct { - Match string `yaml:"match,omitempty"` - DHCP bool `yaml:"dhcp,omitempty"` - Address string `yaml:"address,omitempty"` - IPV4LL bool `yaml:"ipv4ll,omitempty"` - Gateway string `yaml:"gateway,omitempty"` - MTU int `yaml:"mtu,omitempty"` - Bridge bool `yaml:"bridge,omitempty"` -} - type DockerConfig struct { TLS bool `yaml:"tls,omitempty"` TLSArgs []string `yaml:"tls_args,flow,omitempty"`