initial commit of simple ipv6 support
As soon as in warewulf.conf a value for ipaddr6 is defined all nodes will get a derived ipv6 address if not the ipv6 is not explicitly set.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package add
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
|
||||
@@ -123,7 +126,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
|
||||
n.NetDevs[SetNetName].Type.Set(SetType)
|
||||
}
|
||||
if SetIpaddr6 != "" {
|
||||
if SetNetName == "" {
|
||||
return errors.New("you must include the '--netname' option")
|
||||
}
|
||||
if _, ok := n.NetDevs[SetNetName]; !ok {
|
||||
return errors.New("network device does not exist: " + SetNetName)
|
||||
}
|
||||
// just check if address is a valid ipv6 CIDR address
|
||||
if _, _, err := net.ParseCIDR(SetIpaddr6); err != nil {
|
||||
return errors.New(fmt.Sprintf("%s is not a valid ipv6 address in CIDR notation\n", SetIpaddr6))
|
||||
}
|
||||
|
||||
}
|
||||
if SetDiscoverable {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to discoverable\n", n.Id.Get())
|
||||
|
||||
|
||||
@@ -5,16 +5,17 @@ import "github.com/spf13/cobra"
|
||||
var (
|
||||
baseCmd = &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "add [OPTIONS] NODENAME",
|
||||
Short: "Add new node to Warewulf",
|
||||
Long: "This command will add a new node named NODENAME to Warewulf.",
|
||||
RunE: CobraRunE,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Use: "add [OPTIONS] NODENAME",
|
||||
Short: "Add new node to Warewulf",
|
||||
Long: "This command will add a new node named NODENAME to Warewulf.",
|
||||
RunE: CobraRunE,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
}
|
||||
SetClusterName string
|
||||
SetNetName string
|
||||
SetNetDev string
|
||||
SetIpaddr string
|
||||
SetIpaddr6 string
|
||||
SetNetmask string
|
||||
SetGateway string
|
||||
SetHwaddr string
|
||||
@@ -27,6 +28,7 @@ func init() {
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetName, "netname", "n", "default", "Define the network name to configure")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetDev, "netdev", "N", "", "Define the network device to configure")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetIpaddr, "ipaddr", "I", "", "Set the node's network device IP address")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetIpaddr6, "ipaddr6", "6", "", "Set the node's network device IPv6 address")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetmask, "netmask", "M", "", "Set the node's network device netmask")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "H", "", "Set the node's network device HW address")
|
||||
|
||||
@@ -65,6 +65,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":DEVICE", netdev.Device.Source(), netdev.Device.Print())
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":HWADDR", netdev.Hwaddr.Source(), netdev.Hwaddr.Print())
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":IPADDR", netdev.Ipaddr.Source(), netdev.Ipaddr.Print())
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":IPADDR6", netdev.Ipaddr.Source(), netdev.Ipaddr6.Print())
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":NETMASK", netdev.Netmask.Source(), netdev.Netmask.Print())
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":GATEWAY", netdev.Gateway.Source(), netdev.Gateway.Print())
|
||||
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":TYPE", netdev.Type.Source(), netdev.Type.Print())
|
||||
@@ -75,16 +76,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
} else if ShowNet {
|
||||
fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", "NODE NAME", "DEVICE", "HWADDR", "IPADDR", "GATEWAY")
|
||||
fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", "NODE NAME", "DEVICE", "HWADDR", "IPADDR", "GATEWAY", "IPADDR6")
|
||||
fmt.Println(strings.Repeat("=", 80))
|
||||
|
||||
for _, node := range node.FilterByName(nodes, args) {
|
||||
if len(node.NetDevs) > 0 {
|
||||
for name, dev := range node.NetDevs {
|
||||
fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", node.Id.Get(), name, dev.Hwaddr.Print(), dev.Ipaddr.Print(), dev.Gateway.Print())
|
||||
fmt.Printf("%-22s %-6s %-18s %-15s %-15s %-15s\n",
|
||||
node.Id.Get(), name, dev.Hwaddr.Print(), dev.Ipaddr.Print(), dev.Gateway.Print(), dev.Ipaddr6.Print())
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", node.Id.Get(), "--", "--", "--", "--")
|
||||
fmt.Printf("%-22s %-6s %-18s %-15s %-15s %-15s\n", node.Id.Get(), "--", "--", "--", "--", "--")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,15 @@ package node
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/buildconfig"
|
||||
"github.com/hpcng/warewulf/internal/pkg/warewulfconf"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
@@ -43,7 +46,10 @@ func New() (nodeYaml, error) {
|
||||
|
||||
func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
wwconfig, err := warewulfconf.New()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
wwlog.Printf(wwlog.DEBUG, "Finding all nodes...\n")
|
||||
for nodename, node := range config.Nodes {
|
||||
var n NodeInfo
|
||||
@@ -103,13 +109,28 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
}
|
||||
n.NetDevs[devname].Device.Set(netdev.Device)
|
||||
n.NetDevs[devname].Ipaddr.Set(netdev.Ipaddr)
|
||||
n.NetDevs[devname].Ipaddr6.Set(netdev.Ipaddr6)
|
||||
|
||||
// Derive value of ipv6 address from ipv4 if not explicitly set
|
||||
if wwconfig.Ipaddr6 != "" {
|
||||
ipv4Arr := strings.Split(netdev.Ipaddr, ".")
|
||||
// error can be ignored as check was done at init
|
||||
_, ipv6Net, _ := net.ParseCIDR(wwconfig.Ipaddr6)
|
||||
mSize, _ := ipv6Net.Mask.Size()
|
||||
ipv6str := fmt.Sprintf("%s%s:%s:%s:%s/%v",
|
||||
ipv6Net.IP.String(), ipv4Arr[0], ipv4Arr[1], ipv4Arr[2], ipv4Arr[3], mSize)
|
||||
if strings.Count(ipv6Net.IP.String(), ":") == 5 {
|
||||
ipv6str = strings.Replace(ipv6str, "::", ":", -1)
|
||||
}
|
||||
n.NetDevs[devname].Ipaddr6.SetDefault(ipv6str)
|
||||
}
|
||||
n.NetDevs[devname].Netmask.Set(netdev.Netmask)
|
||||
n.NetDevs[devname].Hwaddr.Set(netdev.Hwaddr)
|
||||
n.NetDevs[devname].Gateway.Set(netdev.Gateway)
|
||||
n.NetDevs[devname].Type.Set(netdev.Type)
|
||||
n.NetDevs[devname].OnBoot.Set(netdev.OnBoot)
|
||||
n.NetDevs[devname].Default.Set(netdev.Default)
|
||||
// for just one netdeve, it is always the default
|
||||
// for just one netdev, it is always the default
|
||||
if len(node.NetDevs) == 1 {
|
||||
n.NetDevs[devname].Default.Set("true")
|
||||
}
|
||||
@@ -174,7 +195,7 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
wwlog.Printf(wwlog.DEBUG, "Updating profile (%s) netdev: %s\n", p, devname)
|
||||
|
||||
n.NetDevs[devname].Device.SetAlt(netdev.Device, p)
|
||||
n.NetDevs[devname].Ipaddr.SetAlt(netdev.Ipaddr, p)
|
||||
//n.NetDevs[devname].Ipaddr.SetAlt(netdev.Ipaddr, p) <- Ipaddr must be uniq
|
||||
n.NetDevs[devname].Netmask.SetAlt(netdev.Netmask, p)
|
||||
n.NetDevs[devname].Hwaddr.SetAlt(netdev.Hwaddr, p)
|
||||
n.NetDevs[devname].Gateway.SetAlt(netdev.Gateway, p)
|
||||
|
||||
@@ -49,6 +49,7 @@ type NetDevs struct {
|
||||
Hwaddr string `yaml:"hwaddr,omitempty"`
|
||||
Ipaddr string `yaml:"ipaddr,omitempty"`
|
||||
IpCIDR string `yaml:"ipcidr,omitempty"`
|
||||
Ipaddr6 string `yaml:"ip6addr,omitempty"`
|
||||
Prefix string `yaml:"prefix,omitempty"`
|
||||
Netmask string `yaml:"netmask,omitempty"`
|
||||
Gateway string `yaml:"gateway,omitempty"`
|
||||
@@ -101,6 +102,7 @@ type NetDevEntry struct {
|
||||
Device Entry
|
||||
Hwaddr Entry
|
||||
Ipaddr Entry
|
||||
Ipaddr6 Entry
|
||||
IpCIDR Entry
|
||||
Prefix Entry
|
||||
Netmask Entry
|
||||
|
||||
@@ -33,8 +33,10 @@ type TemplateStruct struct {
|
||||
BuildTime string
|
||||
BuildSource string
|
||||
Ipaddr string
|
||||
Ipaddr6 string
|
||||
Netmask string
|
||||
Network string
|
||||
Ipv6 bool
|
||||
Dhcp warewulfconf.DhcpConf
|
||||
Nfs warewulfconf.NfsConf
|
||||
Warewulf warewulfconf.WarewulfConf
|
||||
|
||||
@@ -205,7 +205,7 @@ func BuildOverlay(nodeInfo node.NodeInfo, overlayName string) error {
|
||||
netPrefix, _ := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4()).Size()
|
||||
tstruct.NetDevs[devname].Prefix = strconv.Itoa(netPrefix)
|
||||
tstruct.NetDevs[devname].IpCIDR = netaddr.String()
|
||||
|
||||
tstruct.NetDevs[devname].Ipaddr6 = netdev.Ipaddr6.Get()
|
||||
}
|
||||
// Backwards compatibility for templates using "Keys"
|
||||
for keyname, key := range nodeInfo.Tags {
|
||||
@@ -219,8 +219,14 @@ func BuildOverlay(nodeInfo node.NodeInfo, overlayName string) error {
|
||||
tstruct.Dhcp = *controller.Dhcp
|
||||
tstruct.Warewulf = *controller.Warewulf
|
||||
tstruct.Ipaddr = controller.Ipaddr
|
||||
tstruct.Ipaddr6 = controller.Ipaddr6
|
||||
tstruct.Netmask = controller.Netmask
|
||||
tstruct.Network = controller.Network
|
||||
if controller.Ipaddr6 != "" {
|
||||
tstruct.Ipv6 = true
|
||||
} else {
|
||||
tstruct.Ipv6 = false
|
||||
}
|
||||
hostname, _ := os.Hostname()
|
||||
tstruct.BuildHost = hostname
|
||||
dt := time.Now()
|
||||
|
||||
@@ -62,7 +62,18 @@ func New() (ControllerConf, error) {
|
||||
|
||||
ret.Network = sub.GetNetworkPortion()
|
||||
}
|
||||
|
||||
// check validity of ipv6 net
|
||||
if ret.Ipaddr6 != "" {
|
||||
_, ipv6net, err := net.ParseCIDR(ret.Ipaddr6)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "Invalid ipv6 address specified, mut be CIDR notation: %s\n", ret.Ipaddr6)
|
||||
return ret, errors.New("invalid ipv6 network")
|
||||
}
|
||||
if msize, _ := ipv6net.Mask.Size(); msize > 64 {
|
||||
wwlog.Printf(wwlog.ERROR, "ipv6 mask size must be smaller than 64\n")
|
||||
return ret, errors.New("invalid ipv6 network size")
|
||||
}
|
||||
}
|
||||
if ret.Warewulf.Port == 0 {
|
||||
ret.Warewulf.Port = defaultPort
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ import (
|
||||
type ControllerConf struct {
|
||||
Comment string `yaml:"comment,omitempty"`
|
||||
Ipaddr string `yaml:"ipaddr"`
|
||||
Ipaddr6 string `yaml:"ipaddr6,omitempty"`
|
||||
Netmask string `yaml:"netmask"`
|
||||
Network string `yaml:"network,omitempty"`
|
||||
Ipv6net string `yaml:"ipv6net,omitempty"`
|
||||
Fqdn string `yaml:"fqdn,omitempty"`
|
||||
Warewulf *WarewulfConf `yaml:"warewulf"`
|
||||
Dhcp *DhcpConf `yaml:"dhcp"`
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
DEVICE={{$.NetDevs.default.Device}}
|
||||
# This file is autogenerated by warewulf
|
||||
# Host: {{.BuildHost}}
|
||||
# Time: {{.BuildTime}}
|
||||
# Source: {{.BuildSource}}
|
||||
# DEVICE={{$.NetDevs.default.Device}}
|
||||
NAME=default
|
||||
BOOTPROTO=static
|
||||
DEVTIMEOUT=10
|
||||
@@ -6,4 +10,11 @@ IPADDR={{$.NetDevs.default.Ipaddr}}
|
||||
NETMASK={{$.NetDevs.default.Netmask}}
|
||||
GATEWAY={{$.NetDevs.default.Gateway}}
|
||||
HWADDR={{$.NetDevs.default.Hwaddr}}
|
||||
ONBOOT=yes
|
||||
ONBOOT=yes
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=yes
|
||||
IPV6_DEFROUTE=yes
|
||||
IPV6_FAILURE_FATAL=no
|
||||
{{- if $.NetDevs.default.Ipaddr6 }}
|
||||
IPV6ADDR="{{ $.NetDevs.default.Ipaddr6 }}"
|
||||
{{- end }}
|
||||
@@ -1,3 +1,9 @@
|
||||
<!--
|
||||
This file is autogenerated by warewulf
|
||||
Host: {{.BuildHost}}
|
||||
Time: {{.BuildTime}}
|
||||
Source: {{.BuildSource}}
|
||||
-->
|
||||
<interface origin="static generated warewulf config">
|
||||
<name>{{.NetDevs.default.Device}}</name>
|
||||
<control>
|
||||
@@ -24,4 +30,11 @@
|
||||
<privacy>prefer-public</privacy>
|
||||
<accept-redirects>false</accept-redirects>
|
||||
</ipv6>
|
||||
{{- if $.NetDevs.default.Ipaddr6 }}
|
||||
<ipv6:static>
|
||||
<address>
|
||||
<local>{{ $.NetDevs.default.Ipaddr6 }}</local>
|
||||
</address>
|
||||
</ipv6:static>
|
||||
{{- end }}
|
||||
</interface>
|
||||
|
||||
Reference in New Issue
Block a user