mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2024-12-13 18:11:25 +01:00
209 lines
4.4 KiB
Go
209 lines
4.4 KiB
Go
package robin
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
|
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
|
|
"github.com/tim-beatham/wgmesh/pkg/ip"
|
|
"github.com/tim-beatham/wgmesh/pkg/ipc"
|
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
|
"github.com/tim-beatham/wgmesh/pkg/mesh"
|
|
"github.com/tim-beatham/wgmesh/pkg/rpc"
|
|
"github.com/tim-beatham/wgmesh/pkg/wg"
|
|
)
|
|
|
|
type RobinIpc struct {
|
|
Server *ctrlserver.MeshCtrlServer
|
|
ipAllocator ip.IPAllocator
|
|
}
|
|
|
|
func (n *RobinIpc) CreateMesh(args *ipc.NewMeshArgs, reply *string) error {
|
|
wg.CreateInterface(args.IfName)
|
|
|
|
meshId, err := n.Server.MeshManager.CreateMesh(args.IfName, args.WgPort)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pubKey, err := n.Server.MeshManager.GetPublicKey(meshId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
nodeIP, err := n.ipAllocator.GetIP(*pubKey, meshId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
outBoundIp := lib.GetOutboundIP()
|
|
|
|
meshNode := crdt.MeshNodeCrdt{
|
|
HostEndpoint: fmt.Sprintf("%s:%s", outBoundIp.String(), n.Server.Conf.GrpcPort),
|
|
PublicKey: pubKey.String(),
|
|
WgEndpoint: fmt.Sprintf("%s:%d", outBoundIp.String(), args.WgPort),
|
|
WgHost: nodeIP.String() + "/128",
|
|
Routes: map[string]interface{}{},
|
|
}
|
|
|
|
n.Server.MeshManager.AddMeshNode(meshId, meshNode)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*reply = meshId
|
|
return nil
|
|
}
|
|
|
|
func (n *RobinIpc) ListMeshes(_ string, reply *ipc.ListMeshReply) error {
|
|
meshNames := make([]string, len(n.Server.MeshManager.Meshes))
|
|
|
|
i := 0
|
|
for _, mesh := range n.Server.MeshManager.Meshes {
|
|
meshNames[i] = mesh.MeshId
|
|
i++
|
|
}
|
|
|
|
*reply = ipc.ListMeshReply{Meshes: meshNames}
|
|
return nil
|
|
}
|
|
|
|
func (n *RobinIpc) JoinMesh(args ipc.JoinMeshArgs, reply *string) error {
|
|
peerConnection, err := n.Server.ConnectionManager.GetConnection(args.IpAdress)
|
|
|
|
client, err := peerConnection.GetClient()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
c := rpc.NewMeshCtrlServerClient(client)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
|
|
meshReply, err := c.GetMesh(ctx, &rpc.GetMeshRequest{MeshId: args.MeshId})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = n.Server.MeshManager.AddMesh(args.MeshId, args.IfName, args.Port, meshReply.Mesh)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pubKey, err := n.Server.MeshManager.GetPublicKey(args.MeshId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ipAddr, err := n.ipAllocator.GetIP(*pubKey, args.MeshId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logging.Log.WriteInfof("WgIP: " + ipAddr.String())
|
|
|
|
outBoundIP := lib.GetOutboundIP()
|
|
|
|
node := crdt.MeshNodeCrdt{
|
|
HostEndpoint: fmt.Sprintf("%s:%s", outBoundIP.String(), n.Server.Conf.GrpcPort),
|
|
WgEndpoint: fmt.Sprintf("%s:%d", outBoundIP.String(), args.Port),
|
|
PublicKey: pubKey.String(),
|
|
WgHost: ipAddr.String() + "/128",
|
|
Routes: make(map[string]interface{}),
|
|
}
|
|
|
|
n.Server.MeshManager.AddMeshNode(args.MeshId, node)
|
|
*reply = strconv.FormatBool(true)
|
|
return nil
|
|
}
|
|
|
|
func (n *RobinIpc) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
|
|
mesh := n.Server.MeshManager.GetMesh(meshId)
|
|
meshSnapshot, err := mesh.GetCrdt()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if mesh != nil {
|
|
nodes := make([]ctrlserver.MeshNode, len(meshSnapshot.Nodes))
|
|
|
|
i := 0
|
|
for _, node := range meshSnapshot.Nodes {
|
|
node := ctrlserver.MeshNode{
|
|
HostEndpoint: node.HostEndpoint,
|
|
WgEndpoint: node.WgEndpoint,
|
|
PublicKey: node.PublicKey,
|
|
WgHost: node.WgHost,
|
|
Failed: mesh.HasFailed(node.HostEndpoint),
|
|
Timestamp: node.Timestamp,
|
|
Routes: lib.MapKeys(node.Routes),
|
|
}
|
|
|
|
nodes[i] = node
|
|
i += 1
|
|
}
|
|
|
|
*reply = ipc.GetMeshReply{Nodes: nodes}
|
|
} else {
|
|
return errors.New("mesh does not exist")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (n *RobinIpc) EnableInterface(meshId string, reply *string) error {
|
|
err := n.Server.MeshManager.EnableInterface(meshId)
|
|
|
|
if err != nil {
|
|
*reply = err.Error()
|
|
return err
|
|
}
|
|
|
|
*reply = "up"
|
|
return nil
|
|
}
|
|
|
|
func (n *RobinIpc) GetDOT(meshId string, reply *string) error {
|
|
g := mesh.NewMeshDotConverter(n.Server.MeshManager)
|
|
|
|
result, err := g.Generate(meshId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*reply = result
|
|
return nil
|
|
}
|
|
|
|
type RobinIpcParams struct {
|
|
CtrlServer *ctrlserver.MeshCtrlServer
|
|
Allocator ip.IPAllocator
|
|
}
|
|
|
|
func NewRobinIpc(ipcParams RobinIpcParams) RobinIpc {
|
|
return RobinIpc{
|
|
Server: ipcParams.CtrlServer,
|
|
ipAllocator: ipcParams.Allocator,
|
|
}
|
|
}
|