Skip to content

Commit

Permalink
NET-715: Ability to set custom interface names (#626)
Browse files Browse the repository at this point in the history
* interface set command,allow multiple docker containers to run on same host

* set interface name on init

* add flag to restart daemon on interface cmd

* save config to disk

* set interface on daemon startup

* add check to validate interface name

* don't restart on setting interface in docker to avoid duplicacy

* remove exact args

* set interface before installing

* set iface name

* add interface flag to join,push cmds

* add iface args to docker script

* remove darwin check

* delete ifaces

* push trap cmd to background

* fix if stmt in script

* fix if stmt in script

* fix docker script

* rm sleep

* wait on trap command

* fix cleanup cmd

* rm debug stmts

* delete only interface spun by this container

* fix overriting of config from in memory
  • Loading branch information
abhishek9686 authored Dec 2, 2023
1 parent 95a2ced commit 5edef5a
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 28 deletions.
2 changes: 2 additions & 0 deletions cmd/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ user: netclient join -s <server> -u <user_name> // attempt to join/register via

Run: func(cmd *cobra.Command, args []string) {
setHostFields(cmd)
functions.Push(false)
token, err := cmd.Flags().GetString(registerFlags.Token)
if err != nil || len(token) == 0 {
if regErr := checkUserRegistration(cmd); regErr != nil {
Expand All @@ -48,5 +49,6 @@ func init() {
joinCmd.Flags().StringP(registerFlags.MTU, "m", "", "sets MTU on host")
joinCmd.Flags().BoolP(registerFlags.Static, "i", false, "flag to set host as static")
joinCmd.Flags().StringP(registerFlags.Name, "o", "", "sets host name")
joinCmd.Flags().StringP(registerFlags.Interface, "I", "", "sets netmaker interface to use on host")
rootCmd.AddCommand(joinCmd)
}
3 changes: 2 additions & 1 deletion cmd/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var pushCmd = &cobra.Command{
Long: `updates host config locally and updates server`,
Run: func(cmd *cobra.Command, args []string) {
setHostFields(cmd)
err := functions.Push()
err := functions.Push(true)
if err != nil {
logger.Log(0, "failed to push", err.Error())
}
Expand All @@ -26,5 +26,6 @@ func init() {
pushCmd.Flags().IntP(registerFlags.MTU, "m", 0, "sets MTU on host")
pushCmd.Flags().BoolP(registerFlags.Static, "i", false, "flag to set host as static")
pushCmd.Flags().StringP(registerFlags.Name, "o", "", "sets host name")
pushCmd.Flags().StringP(registerFlags.Interface, "I", "", "sets netmaker interface to use on host")
rootCmd.AddCommand(pushCmd)
}
41 changes: 40 additions & 1 deletion cmd/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"fmt"
"net"
"os"
"runtime"
"strings"
"syscall"

"github.com/gravitl/netclient/config"
Expand All @@ -27,6 +29,7 @@ var registerFlags = struct {
Port string
MTU string
Static string
Interface string
Name string
}{
Server: "server",
Expand All @@ -39,6 +42,7 @@ var registerFlags = struct {
MTU: "mtu",
Static: "static",
Name: "name",
Interface: "interface",
}

// registerCmd represents the register command
Expand All @@ -53,6 +57,7 @@ all-networks: netclient register -s <server> -A // attempt to register to all al
user: netclient register -s <server> -u <user_name> // attempt to join/register via basic auth`,
Run: func(cmd *cobra.Command, args []string) {
setHostFields(cmd)
functions.Push(false)
token, err := cmd.Flags().GetString(registerFlags.Token)
if err != nil || len(token) == 0 {
if regErr := checkUserRegistration(cmd); regErr != nil {
Expand Down Expand Up @@ -86,11 +91,44 @@ func setHostFields(cmd *cobra.Command) {
if hostName, err := cmd.Flags().GetString(registerFlags.Name); err == nil && hostName != "" {
config.Netclient().Name = hostName
}

if ifaceName, err := cmd.Flags().GetString(registerFlags.Interface); err == nil && ifaceName != "" {
if !validateIface(ifaceName) {
fmt.Println("invalid interface name", ifaceName)
os.Exit(1)
}
config.Netclient().Interface = ifaceName
}
if isStatic, err := cmd.Flags().GetBool(registerFlags.Static); err == nil {
config.Netclient().IsStatic = isStatic
}
}
func validateIface(iface string) bool {
if iface == "" {
return false
}
exists, err := ncutils.InterfaceExists(iface)
if err != nil {
fmt.Println("error checking for interfaces ", err)
return false
}
if exists {
fmt.Printf("iface `%s` already exists\n", iface)
return false
}
if iface == "netmaker-test" || iface == "utun70" {
fmt.Println("cannot use `netmaker-test` interface")
return false
}
if runtime.GOOS == "darwin" && !strings.HasPrefix(iface, "utun") {
fmt.Println("use utun as interface on darwin")
return false
}
if runtime.GOOS != "darwin" && !strings.HasPrefix(iface, "netmaker") {
fmt.Println("invalid interface name, should contain `netmaker` as prefix")
return false
}
return true
}

func checkUserRegistration(cmd *cobra.Command) error {
apiURI, err := cmd.Flags().GetString(registerFlags.Server)
Expand Down Expand Up @@ -140,5 +178,6 @@ func init() {
registerCmd.Flags().IntP(registerFlags.MTU, "m", 0, "sets MTU on host")
registerCmd.Flags().BoolP(registerFlags.Static, "i", false, "flag to set host as static")
registerCmd.Flags().StringP(registerFlags.Name, "o", "", "sets host name")
registerCmd.Flags().StringP(registerFlags.Interface, "I", "", "sets netmaker interface to use on host")
rootCmd.AddCommand(registerCmd)
}
6 changes: 4 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/gravitl/netclient/ncutils"
"github.com/gravitl/netclient/wireguard"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/crypto/nacl/box"
Expand Down Expand Up @@ -79,6 +78,9 @@ func initConfig() {
func InitConfig(viper *viper.Viper) {
config.CheckUID()
config.ReadNetclientConfig()
if config.Netclient().Interface != "" {
ncutils.SetInterfaceName(config.Netclient().Interface)
}
setupLogging(viper)
config.ReadNodeConfig()
config.ReadServerConf()
Expand Down Expand Up @@ -202,7 +204,7 @@ func checkConfig() {
}
if netclient.Interface == "" {
logger.Log(0, "setting wireguard interface")
netclient.Interface = models.WIREGUARD_INTERFACE
netclient.Interface = ncutils.GetInterfaceName()
saveRequired = true
}
if netclient.ListenPort == 0 {
Expand Down
1 change: 1 addition & 0 deletions functions/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func startGoRoutines(wg *sync.WaitGroup) context.CancelFunc {
slog.Error("error reading netclient config file", "error", err)
}
config.UpdateNetclient(*config.Netclient())
ncutils.SetInterfaceName(config.Netclient().Interface)
if err := config.ReadServerConf(); err != nil {
slog.Warn("error reading server map from disk", "error", err)
}
Expand Down
2 changes: 1 addition & 1 deletion functions/localport.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func getInterfaces() (*[]models.Iface, error) {
if iface.Flags&net.FlagUp == 0 || // interface down
iface.Flags&net.FlagLoopback != 0 || // loopback interface
iface.Flags&net.FlagPointToPoint != 0 || // avoid direct connections
iface.Name == ncutils.GetInterfaceName() || // avoid netmaker
iface.Name == ncutils.GetInterfaceName() || strings.Contains(iface.Name, "netmaker") || // avoid netmaker
ncutils.IsBridgeNetwork(iface.Name) || // avoid bridges
strings.Contains(iface.Name, "docker") {
continue
Expand Down
27 changes: 14 additions & 13 deletions functions/push.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package functions

import (
"errors"
"fmt"

"github.com/gravitl/netclient/config"
Expand All @@ -10,24 +9,26 @@ import (
)

// Push - updates server with new host config
func Push() error {
func Push(restart bool) error {
server := config.GetServer(config.CurrServer)
if server == nil {
return errors.New("server cfg is nil")
}
if err := setupMQTTSingleton(server, true); err != nil {
return err
}
if err := PublishHostUpdate(server.Server, models.UpdateHost); err != nil {
return err
if server != nil {
if err := setupMQTTSingleton(server, true); err != nil {
return err
}
if err := PublishHostUpdate(server.Server, models.UpdateHost); err != nil {
return err
}
}
if err := config.WriteNetclientConfig(); err != nil {
return err
}
if err := daemon.Restart(); err != nil {
if err := daemon.Start(); err != nil {
return fmt.Errorf("daemon restart failed %w", err)
if restart {
if err := daemon.Restart(); err != nil {
if err := daemon.Start(); err != nil {
return fmt.Errorf("daemon restart failed %w", err)
}
}
}

return nil
}
26 changes: 26 additions & 0 deletions ncutils/netclientutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"github.com/gravitl/netmaker/models"
)

var ifaceName string

// MaxNameLength - maximum node name length
const MaxNameLength = 62

Expand Down Expand Up @@ -538,8 +540,18 @@ func IPIsPrivate(ipnet net.IP) bool {
return ipnet.IsPrivate() || ipnet.IsLoopback()
}

func SetInterfaceName(iface string) {
if runtime.GOOS == "darwin" && !strings.HasPrefix(iface, "utun") {
return
}
ifaceName = iface
}

// GetInterfaceName - fetches the interface name
func GetInterfaceName() string {
if ifaceName != "" {
return ifaceName
}
if runtime.GOOS == "darwin" {
return "utun69"
}
Expand Down Expand Up @@ -579,3 +591,17 @@ func RandomString(length int) string {
func ConvHostPassToHash(hostPass string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(hostPass)))
}

// InterfaceExists - checks if iface exists already
func InterfaceExists(ifaceName string) (bool, error) {
interfaces, err := net.Interfaces()
if err != nil {
return false, err
}
for _, inet := range interfaces {
if inet.Name == ifaceName {
return true, nil
}
}
return false, nil
}
31 changes: 21 additions & 10 deletions scripts/netclient.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
sh -c rc-status
#Define cleanup
cleanup() {
nets=($(wg show interfaces))
for net in ${nets[@]}; do
echo "deleting interface" $net
ip link del $net
done
echo "deleting interface" $net
if [ "${IFACE_NAME}" == "" ];then
IFACE_NAME="netmaker"
fi
ip link del $IFACE_NAME
}

#Trap SigTerm
trap 'cleanup' SIGTERM


# install netclient
echo "[netclient] starting netclient daemon"
Expand Down Expand Up @@ -59,8 +58,20 @@ STATIC_CMD=""
if [ "${IS_STATIC}" != "" ];then
STATIC_CMD="-i ${IS_STATIC}"
fi
IFACE_CMD=""
if [ "${IFACE_NAME}" != "" ];then
IFACE_CMD="-I ${IFACE_NAME}"
fi

netclient join $TOKEN_CMD $PORT_CMD $ENDPOINT_CMD $MTU_CMD $HOSTNAME_CMD $STATIC_CMD
if [ $? -ne 0 ]; then { echo "failed to join, quitting." ; exit 1; } fi
echo "[netclient] Starting netclient daemon"
/root/netclient install
wait $!
netclient join $TOKEN_CMD $PORT_CMD $ENDPOINT_CMD $MTU_CMD $HOSTNAME_CMD $STATIC_CMD $IFACE_CMD
if [ $? -ne 0 ]; then { echo "Failed to join, quitting." ; exit 1; } fi

sleep infinity
tail -f /var/log/netclient.log &

#Trap SigTerm
trap 'cleanup' SIGTERM

wait $!

0 comments on commit 5edef5a

Please sign in to comment.