2023-09-18 13:59:28 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2023-09-18 16:52:28 +02:00
|
|
|
"fmt"
|
2023-09-19 19:29:35 +02:00
|
|
|
ipcRpc "net/rpc"
|
2023-09-18 16:52:28 +02:00
|
|
|
"os"
|
2023-10-25 19:34:38 +02:00
|
|
|
"strings"
|
2023-10-24 17:00:46 +02:00
|
|
|
"time"
|
2023-09-18 16:52:28 +02:00
|
|
|
|
|
|
|
"github.com/akamensky/argparse"
|
2023-11-27 19:55:41 +01:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/ctrlserver"
|
2023-09-19 19:29:35 +02:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/ipc"
|
2023-11-27 19:55:41 +01:00
|
|
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
2023-10-06 19:25:38 +02:00
|
|
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
2023-09-18 13:59:28 +02:00
|
|
|
)
|
|
|
|
|
2023-09-18 18:00:43 +02:00
|
|
|
const SockAddr = "/tmp/wgmesh_ipc.sock"
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
type CreateMeshParams struct {
|
|
|
|
Client *ipcRpc.Client
|
|
|
|
WgPort int
|
|
|
|
Endpoint string
|
|
|
|
}
|
|
|
|
|
|
|
|
func createMesh(args *CreateMeshParams) string {
|
2023-09-18 18:00:43 +02:00
|
|
|
var reply string
|
2023-10-24 17:00:46 +02:00
|
|
|
newMeshParams := ipc.NewMeshArgs{
|
2023-10-28 17:38:25 +02:00
|
|
|
WgPort: args.WgPort,
|
|
|
|
Endpoint: args.Endpoint,
|
2023-10-24 17:00:46 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
err := args.Client.Call("IpcHandler.CreateMesh", &newMeshParams, &reply)
|
2023-09-18 18:00:43 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-09-20 00:50:44 +02:00
|
|
|
return err.Error()
|
2023-09-18 18:00:43 +02:00
|
|
|
}
|
|
|
|
|
2023-09-20 00:50:44 +02:00
|
|
|
return reply
|
2023-09-18 18:00:43 +02:00
|
|
|
}
|
|
|
|
|
2023-09-19 19:29:35 +02:00
|
|
|
func listMeshes(client *ipcRpc.Client) {
|
2023-10-06 19:25:38 +02:00
|
|
|
reply := new(ipc.ListMeshReply)
|
2023-09-19 14:45:49 +02:00
|
|
|
|
2023-10-26 17:53:12 +02:00
|
|
|
err := client.Call("IpcHandler.ListMeshes", "", &reply)
|
2023-09-19 14:45:49 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-10-24 01:12:38 +02:00
|
|
|
logging.Log.WriteErrorf(err.Error())
|
2023-09-19 14:45:49 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-10-06 19:25:38 +02:00
|
|
|
for _, meshId := range reply.Meshes {
|
|
|
|
fmt.Println(meshId)
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
type JoinMeshParams struct {
|
|
|
|
Client *ipcRpc.Client
|
|
|
|
MeshId string
|
|
|
|
IpAddress string
|
|
|
|
IfName string
|
|
|
|
WgPort int
|
|
|
|
Endpoint string
|
|
|
|
}
|
|
|
|
|
|
|
|
func joinMesh(params *JoinMeshParams) string {
|
2023-09-19 19:29:35 +02:00
|
|
|
var reply string
|
|
|
|
|
2023-10-24 17:00:46 +02:00
|
|
|
args := ipc.JoinMeshArgs{
|
2023-10-28 17:38:25 +02:00
|
|
|
MeshId: params.MeshId,
|
|
|
|
IpAdress: params.IpAddress,
|
|
|
|
Port: params.WgPort,
|
2023-10-24 17:00:46 +02:00
|
|
|
}
|
2023-09-19 19:29:35 +02:00
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
err := params.Client.Call("IpcHandler.JoinMesh", &args, &reply)
|
2023-09-19 19:29:35 +02:00
|
|
|
|
2023-09-20 00:50:44 +02:00
|
|
|
if err != nil {
|
|
|
|
return err.Error()
|
|
|
|
}
|
|
|
|
|
|
|
|
return reply
|
|
|
|
}
|
|
|
|
|
|
|
|
func getMesh(client *ipcRpc.Client, meshId string) {
|
|
|
|
reply := new(ipc.GetMeshReply)
|
|
|
|
|
2023-10-26 17:53:12 +02:00
|
|
|
err := client.Call("IpcHandler.GetMesh", &meshId, &reply)
|
2023-09-20 00:50:44 +02:00
|
|
|
|
2023-09-19 19:29:35 +02:00
|
|
|
if err != nil {
|
2023-10-28 17:38:25 +02:00
|
|
|
fmt.Println(err.Error())
|
2023-09-19 19:29:35 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-09-20 00:50:44 +02:00
|
|
|
for _, node := range reply.Nodes {
|
|
|
|
fmt.Println("Public Key: " + node.PublicKey)
|
2023-10-06 12:52:51 +02:00
|
|
|
fmt.Println("Control Endpoint: " + node.HostEndpoint)
|
2023-10-06 19:25:38 +02:00
|
|
|
fmt.Println("WireGuard Endpoint: " + node.WgEndpoint)
|
2023-09-20 00:50:44 +02:00
|
|
|
fmt.Println("Wg IP: " + node.WgHost)
|
2023-11-27 19:55:41 +01:00
|
|
|
fmt.Printf("Timestamp: %s", time.Unix(node.Timestamp, 0).String())
|
2023-10-25 19:34:38 +02:00
|
|
|
|
2023-11-27 19:55:41 +01:00
|
|
|
mapFunc := func(r ctrlserver.MeshRoute) string {
|
|
|
|
return r.Destination
|
|
|
|
}
|
|
|
|
|
|
|
|
advertiseRoutes := strings.Join(lib.Map(node.Routes, mapFunc), ",")
|
2023-10-25 19:34:38 +02:00
|
|
|
fmt.Printf("Routes: %s\n", advertiseRoutes)
|
|
|
|
|
2023-09-20 00:50:44 +02:00
|
|
|
fmt.Println("---")
|
|
|
|
}
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
func leaveMesh(client *ipcRpc.Client, meshId string) {
|
|
|
|
var reply string
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.LeaveMesh", &meshId, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-09-21 19:43:29 +02:00
|
|
|
func enableInterface(client *ipcRpc.Client, meshId string) {
|
|
|
|
var reply string
|
|
|
|
|
2023-10-26 17:53:12 +02:00
|
|
|
err := client.Call("IpcHandler.EnableInterface", &meshId, &reply)
|
2023-09-21 19:43:29 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-10-06 12:52:51 +02:00
|
|
|
fmt.Println(err.Error())
|
2023-09-21 19:43:29 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-10-22 14:34:49 +02:00
|
|
|
func getGraph(client *ipcRpc.Client, meshId string) {
|
|
|
|
var reply string
|
|
|
|
|
2023-10-26 17:53:12 +02:00
|
|
|
err := client.Call("IpcHandler.GetDOT", &meshId, &reply)
|
2023-10-22 14:34:49 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-10-30 20:02:28 +01:00
|
|
|
func queryMesh(client *ipcRpc.Client, meshId, query string) {
|
|
|
|
var reply string
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.Query", &ipc.QueryMesh{MeshId: meshId, Query: query}, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-11-01 12:58:10 +01:00
|
|
|
// putDescription: puts updates the description about the node to the meshes
|
|
|
|
func putDescription(client *ipcRpc.Client, description string) {
|
|
|
|
var reply string
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.PutDescription", &description, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-11-17 20:05:21 +01:00
|
|
|
// putAlias: puts an alias for the node
|
|
|
|
func putAlias(client *ipcRpc.Client, alias string) {
|
|
|
|
var reply string
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.PutAlias", &alias, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-11-17 23:13:51 +01:00
|
|
|
func setService(client *ipcRpc.Client, service, value string) {
|
|
|
|
var reply string
|
|
|
|
|
|
|
|
serviceArgs := &ipc.PutServiceArgs{
|
|
|
|
Service: service,
|
|
|
|
Value: value,
|
|
|
|
}
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.PutService", serviceArgs, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
|
|
|
func deleteService(client *ipcRpc.Client, service string) {
|
|
|
|
var reply string
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.PutService", &service, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-11-20 12:28:12 +01:00
|
|
|
func getNode(client *ipcRpc.Client, nodeId, meshId string) {
|
|
|
|
var reply string
|
|
|
|
args := &ipc.GetNodeArgs{
|
|
|
|
NodeId: nodeId,
|
|
|
|
MeshId: meshId,
|
|
|
|
}
|
|
|
|
|
|
|
|
err := client.Call("IpcHandler.GetNode", &args, &reply)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(reply)
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:52:28 +02:00
|
|
|
func main() {
|
|
|
|
parser := argparse.NewParser("wg-mesh",
|
|
|
|
"wg-mesh Manipulate WireGuard meshes")
|
|
|
|
|
|
|
|
newMeshCmd := parser.NewCommand("new-mesh", "Create a new mesh")
|
2023-09-19 14:45:49 +02:00
|
|
|
listMeshCmd := parser.NewCommand("list-meshes", "List meshes the node is connected to")
|
|
|
|
joinMeshCmd := parser.NewCommand("join-mesh", "Join a mesh network")
|
2023-09-21 19:43:29 +02:00
|
|
|
enableInterfaceCmd := parser.NewCommand("enable-interface", "Enable A Specific Mesh Interface")
|
2023-10-22 14:34:49 +02:00
|
|
|
getGraphCmd := parser.NewCommand("get-graph", "Convert a mesh into DOT format")
|
2023-10-28 17:38:25 +02:00
|
|
|
leaveMeshCmd := parser.NewCommand("leave-mesh", "Leave a mesh network")
|
2023-10-30 20:02:28 +01:00
|
|
|
queryMeshCmd := parser.NewCommand("query-mesh", "Query a mesh network using JMESPath")
|
2023-11-01 12:58:10 +01:00
|
|
|
putDescriptionCmd := parser.NewCommand("put-description", "Place a description for the node")
|
2023-11-17 20:05:21 +01:00
|
|
|
putAliasCmd := parser.NewCommand("put-alias", "Place an alias for the node")
|
2023-11-17 23:13:51 +01:00
|
|
|
setServiceCmd := parser.NewCommand("set-service", "Place a service into your advertisements")
|
|
|
|
deleteServiceCmd := parser.NewCommand("delete-service", "Remove a service from your advertisements")
|
2023-11-20 12:28:12 +01:00
|
|
|
getNodeCmd := parser.NewCommand("get-node", "Get a specific node from the mesh")
|
2023-09-19 14:45:49 +02:00
|
|
|
|
2023-11-20 14:03:42 +01:00
|
|
|
var newMeshPort *int = newMeshCmd.Int("p", "wgport", &argparse.Options{})
|
2023-10-28 17:38:25 +02:00
|
|
|
var newMeshEndpoint *string = newMeshCmd.String("e", "endpoint", &argparse.Options{})
|
2023-10-24 17:00:46 +02:00
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
var joinMeshId *string = joinMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
|
|
|
var joinMeshIpAddress *string = joinMeshCmd.String("i", "ip", &argparse.Options{Required: true})
|
2023-11-20 14:03:42 +01:00
|
|
|
var joinMeshPort *int = joinMeshCmd.Int("p", "wgport", &argparse.Options{})
|
2023-10-28 17:38:25 +02:00
|
|
|
var joinMeshEndpoint *string = joinMeshCmd.String("e", "endpoint", &argparse.Options{})
|
2023-10-24 17:00:46 +02:00
|
|
|
|
2023-09-21 19:43:29 +02:00
|
|
|
var enableInterfaceMeshId *string = enableInterfaceCmd.String("m", "mesh", &argparse.Options{Required: true})
|
2023-11-01 12:58:10 +01:00
|
|
|
|
2023-10-22 14:34:49 +02:00
|
|
|
var getGraphMeshId *string = getGraphCmd.String("m", "mesh", &argparse.Options{Required: true})
|
2023-09-20 00:50:44 +02:00
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
var leaveMeshMeshId *string = leaveMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
|
|
|
|
2023-10-30 20:02:28 +01:00
|
|
|
var queryMeshMeshId *string = queryMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
|
|
|
var queryMeshQuery *string = queryMeshCmd.String("q", "query", &argparse.Options{Required: true})
|
|
|
|
|
2023-11-01 12:58:10 +01:00
|
|
|
var description *string = putDescriptionCmd.String("d", "description", &argparse.Options{Required: true})
|
|
|
|
|
2023-11-17 20:05:21 +01:00
|
|
|
var alias *string = putAliasCmd.String("a", "alias", &argparse.Options{Required: true})
|
|
|
|
|
2023-11-17 23:13:51 +01:00
|
|
|
var serviceKey *string = setServiceCmd.String("s", "service", &argparse.Options{Required: true})
|
|
|
|
var serviceValue *string = setServiceCmd.String("v", "value", &argparse.Options{Required: true})
|
|
|
|
|
|
|
|
var deleteServiceKey *string = deleteServiceCmd.String("s", "service", &argparse.Options{Required: true})
|
|
|
|
|
2023-11-20 12:28:12 +01:00
|
|
|
var getNodeNodeId *string = getNodeCmd.String("n", "nodeid", &argparse.Options{Required: true})
|
|
|
|
var getNodeMeshId *string = getNodeCmd.String("m", "meshid", &argparse.Options{Required: true})
|
|
|
|
|
2023-09-18 16:52:28 +02:00
|
|
|
err := parser.Parse(os.Args)
|
2023-09-18 13:59:28 +02:00
|
|
|
|
2023-09-18 16:52:28 +02:00
|
|
|
if err != nil {
|
|
|
|
fmt.Print(parser.Usage(err))
|
|
|
|
return
|
|
|
|
}
|
2023-09-18 13:59:28 +02:00
|
|
|
|
2023-09-19 19:29:35 +02:00
|
|
|
client, err := ipcRpc.DialHTTP("unix", SockAddr)
|
2023-09-18 18:00:43 +02:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err.Error())
|
|
|
|
return
|
|
|
|
}
|
2023-09-18 13:59:28 +02:00
|
|
|
|
2023-09-18 18:00:43 +02:00
|
|
|
if newMeshCmd.Happened() {
|
2023-10-28 17:38:25 +02:00
|
|
|
fmt.Println(createMesh(&CreateMeshParams{
|
|
|
|
Client: client,
|
|
|
|
WgPort: *newMeshPort,
|
|
|
|
Endpoint: *newMeshEndpoint,
|
|
|
|
}))
|
2023-09-18 16:52:28 +02:00
|
|
|
}
|
2023-09-19 14:45:49 +02:00
|
|
|
|
|
|
|
if listMeshCmd.Happened() {
|
|
|
|
listMeshes(client)
|
|
|
|
}
|
|
|
|
|
|
|
|
if joinMeshCmd.Happened() {
|
2023-10-28 17:38:25 +02:00
|
|
|
fmt.Println(joinMesh(&JoinMeshParams{
|
|
|
|
Client: client,
|
|
|
|
WgPort: *joinMeshPort,
|
|
|
|
IpAddress: *joinMeshIpAddress,
|
|
|
|
MeshId: *joinMeshId,
|
|
|
|
Endpoint: *joinMeshEndpoint,
|
|
|
|
}))
|
2023-09-20 00:50:44 +02:00
|
|
|
}
|
|
|
|
|
2023-10-22 14:34:49 +02:00
|
|
|
if getGraphCmd.Happened() {
|
|
|
|
getGraph(client, *getGraphMeshId)
|
|
|
|
}
|
|
|
|
|
2023-09-21 19:43:29 +02:00
|
|
|
if enableInterfaceCmd.Happened() {
|
|
|
|
enableInterface(client, *enableInterfaceMeshId)
|
|
|
|
}
|
2023-10-28 17:38:25 +02:00
|
|
|
|
|
|
|
if leaveMeshCmd.Happened() {
|
|
|
|
leaveMesh(client, *leaveMeshMeshId)
|
|
|
|
}
|
2023-10-30 20:02:28 +01:00
|
|
|
|
|
|
|
if queryMeshCmd.Happened() {
|
|
|
|
queryMesh(client, *queryMeshMeshId, *queryMeshQuery)
|
|
|
|
}
|
2023-11-01 12:58:10 +01:00
|
|
|
|
|
|
|
if putDescriptionCmd.Happened() {
|
|
|
|
putDescription(client, *description)
|
|
|
|
}
|
2023-11-17 20:05:21 +01:00
|
|
|
|
|
|
|
if putAliasCmd.Happened() {
|
|
|
|
putAlias(client, *alias)
|
|
|
|
}
|
2023-11-17 23:13:51 +01:00
|
|
|
|
|
|
|
if setServiceCmd.Happened() {
|
|
|
|
setService(client, *serviceKey, *serviceValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
if deleteServiceCmd.Happened() {
|
|
|
|
deleteService(client, *deleteServiceKey)
|
|
|
|
}
|
2023-11-20 12:28:12 +01:00
|
|
|
|
|
|
|
if getNodeCmd.Happened() {
|
|
|
|
getNode(client, *getNodeNodeId, *getNodeMeshId)
|
|
|
|
}
|
2023-09-18 16:52:28 +02:00
|
|
|
}
|