Browse Source

Expose join to cli

Ettore Di Giacinto 3 years ago
parent
commit
e3cf376c83
3 changed files with 115 additions and 87 deletions
  1. 74 48
      main.go
  2. 16 15
      pkg/edgevpn/connection.go
  3. 25 24
      pkg/edgevpn/edgevpn.go

+ 74 - 48
main.go

@@ -27,6 +27,7 @@ import (
 	"go.uber.org/zap"
 	"gopkg.in/yaml.v2"
 
+	"github.com/mudler/edgevpn/pkg/blockchain"
 	edgevpn "github.com/mudler/edgevpn/pkg/edgevpn"
 )
 
@@ -35,10 +36,46 @@ This program comes with ABSOLUTELY NO WARRANTY.
 This is free software, and you are welcome to redistribute it
 under certain conditions.`
 
+func cliToOpts(l *zap.Logger, c *cli.Context) []edgevpn.Option {
+	config := c.String("config")
+	address := c.String("address")
+	iface := c.String("interface")
+	token := c.String("token")
+	if config == "" &&
+		token == "" {
+		l.Sugar().Fatal("EDGEVPNCONFIG or EDGEVPNTOKEN not supplied. At least a config file is required")
+	}
+	return []edgevpn.Option{
+		edgevpn.Logger(l),
+		edgevpn.LogLevel(log.LevelInfo),
+		edgevpn.MaxMessageSize(2 << 20), // 2MB
+		edgevpn.WithInterfaceMTU(1450),
+		edgevpn.WithPacketMTU(1420),
+		edgevpn.WithInterfaceAddress(address),
+		edgevpn.WithInterfaceName(iface),
+		edgevpn.WithMaxBlockChainSize(1000),
+		edgevpn.WithInterfaceType(water.TUN),
+		edgevpn.NetLinkBootstrap(true),
+		edgevpn.FromBase64(token),
+		edgevpn.FromYaml(config),
+	}
+}
+
 func main() {
 	l, _ := zap.NewProduction()
 	defer l.Sync() // flushes buffer, if any
 
+	common := []cli.Flag{&cli.StringFlag{
+		Name:   "config",
+		Usage:  "Specify a path to a edgevpn config file",
+		EnvVar: "EDGEVPNCONFIG",
+	},
+		&cli.StringFlag{
+			Name:   "token",
+			Usage:  "Specify an edgevpn token in place of a config file",
+			EnvVar: "EDGEVPNTOKEN",
+		}}
+
 	app := &cli.App{
 		Name:        "edgevpn",
 		Version:     internal.Version,
@@ -46,21 +83,11 @@ func main() {
 		Usage:       "edgevpn --config /etc/edgevpn/config.yaml",
 		Description: "edgevpn uses libp2p to build an immutable trusted blockchain addressable p2p network",
 		Copyright:   copyRight,
-		Flags: []cli.Flag{
+		Flags: append([]cli.Flag{
 			&cli.BoolFlag{
 				Name:  "g",
 				Usage: "Generates a new configuration and prints it on screen",
 			},
-			&cli.StringFlag{
-				Name:   "config",
-				Usage:  "Specify a path to a edgevpn config file",
-				EnvVar: "EDGEVPNCONFIG",
-			},
-			&cli.StringFlag{
-				Name:   "token",
-				Usage:  "Specify an edgevpn token in place of a config file",
-				EnvVar: "EDGEVPNTOKEN",
-			},
 			&cli.StringFlag{
 				Name:   "address",
 				Usage:  "VPN virtual address",
@@ -72,8 +99,31 @@ func main() {
 				Usage:  "Interface name",
 				Value:  "edgevpn0",
 				EnvVar: "IFACE",
+			}}, common...),
+
+		Commands: []cli.Command{{
+			Name:        "join",
+			Description: "join the network without activating any interface",
+			Flags:       common,
+			Action: func(c *cli.Context) error {
+				e := edgevpn.New(cliToOpts(l, c)...)
+
+				mw, err := e.MessageWriter()
+				if err != nil {
+					return err
+				}
+
+				ledger := blockchain.New(mw, 1000)
+
+				// Join the node to the network, using our ledger
+				if err := e.Join(ledger); err != nil {
+					return err
+				}
+
+				for {
+				}
 			},
-		},
+		}},
 
 		Action: func(c *cli.Context) error {
 			if c.Bool("g") {
@@ -94,48 +144,24 @@ func main() {
 				os.Exit(0)
 			}
 
-			start(l, c)
-			return nil
-		},
-	}
+			e := edgevpn.New(cliToOpts(l, c)...)
 
-	err := app.Run(os.Args)
-	if err != nil {
-		l.Sugar().Fatal(err)
-	}
-}
-func start(l *zap.Logger, c *cli.Context) {
-	config := c.String("config")
-	address := c.String("address")
-	iface := c.String("interface")
-	token := c.String("token")
+			l.Sugar().Info(copyRight)
 
-	opts := []edgevpn.Option{
-		edgevpn.Logger(l),
-		edgevpn.LogLevel(log.LevelInfo),
-		edgevpn.MaxMessageSize(2 << 20), // 2MB
-		edgevpn.WithInterfaceMTU(1450),
-		edgevpn.WithPacketMTU(1420),
-		edgevpn.WithInterfaceAddress(address),
-		edgevpn.WithInterfaceName(iface),
-		edgevpn.WithMaxBlockChainSize(1000),
-		edgevpn.WithInterfaceType(water.TUN),
-		edgevpn.NetLinkBootstrap(true),
-		edgevpn.FromBase64(token),
-		edgevpn.FromYaml(config),
-	}
+			l.Sugar().Infof("Version: %s commit: %s", internal.Version, internal.Commit)
 
-	e := edgevpn.New(opts...)
+			l.Sugar().Info("Start")
 
-	l.Sugar().Info(copyRight)
+			if err := e.Start(); err != nil {
+				l.Sugar().Fatal(err.Error())
+			}
 
-	l.Sugar().Infof("Version: %s commit: %s", internal.Version, internal.Commit)
-	if config == "" && token == "" {
-		l.Sugar().Fatal("EDGEVPNCONFIG or EDGEVPNTOKEN not supplied. config file is required")
+			return nil
+		},
 	}
-	l.Sugar().Info("Start")
 
-	if err := e.Start(); err != nil {
-		l.Sugar().Fatal(err.Error())
+	err := app.Run(os.Args)
+	if err != nil {
+		l.Sugar().Fatal(err)
 	}
 }

+ 16 - 15
pkg/edgevpn/connection.go

@@ -41,27 +41,28 @@ func (e *EdgeVPN) genHost(ctx context.Context) (host.Host, error) {
 		return nil, err
 	}
 
-	// Avoid to loopback traffic by trying to connect to nodes in via VPN
-	_, vpnNetwork, err := net.ParseCIDR(e.config.InterfaceAddress)
-	if err != nil {
-		return nil, err
-	}
-
-	cg, err := conngater.NewBasicConnectionGater(nil)
-	if err != nil {
-		return nil, err
-	}
-	if err := cg.BlockSubnet(vpnNetwork); err != nil {
-		return nil, err
-	}
-
 	opts := defaultLibp2pOptions
 
 	if len(e.config.Options) != 0 {
 		opts = e.config.Options
 	}
 
-	opts = append(opts, libp2p.ConnectionGater(cg))
+	if e.config.InterfaceAddress != "" {
+		// Avoid to loopback traffic by trying to connect to nodes in via VPN
+		_, vpnNetwork, err := net.ParseCIDR(e.config.InterfaceAddress)
+		if err != nil {
+			return nil, err
+		}
+		cg, err := conngater.NewBasicConnectionGater(nil)
+		if err != nil {
+			return nil, err
+		}
+		if err := cg.BlockSubnet(vpnNetwork); err != nil {
+			return nil, err
+		}
+		opts = append(opts, libp2p.ConnectionGater(cg))
+	}
+
 	opts = append(opts, libp2p.Identity(prvKey))
 
 	addrs := []multiaddr.Multiaddr{}

+ 25 - 24
pkg/edgevpn/edgevpn.go

@@ -48,35 +48,16 @@ func (e *EdgeVPN) Join(ledger *blockchain.Ledger) error {
 	// The ledger needs to read them and update the internal blockchain
 	e.config.Handlers = append(e.config.Handlers, ledger.Update)
 
-	e.config.Logger.Sugar().Info("starting edgevpn background daemon")
-	// Startup libp2p network
-	err := e.network()
-	if err != nil {
-		return err
-	}
+	e.config.Logger.Sugar().Info("starting edgevpn")
 
-	// Avoid to loopback traffic by trying to connect to nodes in via VPN
-	ip, _, err := net.ParseCIDR(e.config.InterfaceAddress)
+	// Startup libp2p network
+	err := e.startNetwork()
 	if err != nil {
 		return err
 	}
 
-	// Updates the blockchain
+	// Send periodically messages to the channel with our blockchain content
 	ledger.Syncronizer(context.Background(), e.config.LedgerSyncronizationTime)
-	ledger.Announce(
-		context.Background(),
-		e.config.LedgerAnnounceTime,
-		func() {
-			// Retrieve current ID for ip in the blockchain
-			existingValue, found := ledger.GetKey(ip.String())
-			// If mismatch, update the blockchain
-			if !found || existingValue.PeerID != e.host.ID().String() {
-				updatedMap := map[string]blockchain.Data{}
-				updatedMap[ip.String()] = blockchain.Data{PeerID: e.host.ID().String()}
-				ledger.Add(updatedMap)
-			}
-		},
-	)
 
 	return nil
 }
@@ -104,6 +85,26 @@ func (e *EdgeVPN) Start() error {
 		return err
 	}
 
+	// Announce our IP
+	ip, _, err := net.ParseCIDR(e.config.InterfaceAddress)
+	if err != nil {
+		return err
+	}
+	ledger.Announce(
+		context.Background(),
+		e.config.LedgerAnnounceTime,
+		func() {
+			// Retrieve current ID for ip in the blockchain
+			existingValue, found := ledger.GetKey(ip.String())
+			// If mismatch, update the blockchain
+			if !found || existingValue.PeerID != e.host.ID().String() {
+				updatedMap := map[string]blockchain.Data{}
+				updatedMap[ip.String()] = blockchain.Data{PeerID: e.host.ID().String()}
+				ledger.Add(updatedMap)
+			}
+		},
+	)
+
 	if e.config.NetLinkBootstrap {
 		if err := e.prepareInterface(); err != nil {
 			return err
@@ -192,7 +193,7 @@ func (e *EdgeVPN) readPackets(ledger *blockchain.Ledger, ifce *water.Interface)
 	}
 }
 
-func (e *EdgeVPN) network() error {
+func (e *EdgeVPN) startNetwork() error {
 	ctx := context.Background()
 	e.config.Logger.Sugar().Info("generating host data")