mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2025-01-06 13:28:49 +01:00
Ability to specify aliases
Ability to specify aliases that automatically append to /etc/hosts
This commit is contained in:
parent
f6160fe138
commit
68db795f47
@ -13,5 +13,5 @@ func main() {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
apiServer.Run(":8080")
|
||||
apiServer.Run(":40000")
|
||||
}
|
||||
|
@ -185,6 +185,37 @@ func putAlias(client *ipcRpc.Client, alias string) {
|
||||
fmt.Println(reply)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func main() {
|
||||
parser := argparse.NewParser("wg-mesh",
|
||||
"wg-mesh Manipulate WireGuard meshes")
|
||||
@ -199,6 +230,8 @@ func main() {
|
||||
queryMeshCmd := parser.NewCommand("query-mesh", "Query a mesh network using JMESPath")
|
||||
putDescriptionCmd := parser.NewCommand("put-description", "Place a description for the node")
|
||||
putAliasCmd := parser.NewCommand("put-alias", "Place an alias for the node")
|
||||
setServiceCmd := parser.NewCommand("set-service", "Place a service into your advertisements")
|
||||
deleteServiceCmd := parser.NewCommand("delete-service", "Remove a service from your advertisements")
|
||||
|
||||
var newMeshIfName *string = newMeshCmd.String("f", "ifname", &argparse.Options{Required: true})
|
||||
var newMeshPort *int = newMeshCmd.Int("p", "wgport", &argparse.Options{Required: true})
|
||||
@ -210,8 +243,6 @@ func main() {
|
||||
var joinMeshPort *int = joinMeshCmd.Int("p", "wgport", &argparse.Options{Required: true})
|
||||
var joinMeshEndpoint *string = joinMeshCmd.String("e", "endpoint", &argparse.Options{})
|
||||
|
||||
// var getMeshId *string = getMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
||||
|
||||
var enableInterfaceMeshId *string = enableInterfaceCmd.String("m", "mesh", &argparse.Options{Required: true})
|
||||
|
||||
var getGraphMeshId *string = getGraphCmd.String("m", "mesh", &argparse.Options{Required: true})
|
||||
@ -225,6 +256,11 @@ func main() {
|
||||
|
||||
var alias *string = putAliasCmd.String("a", "alias", &argparse.Options{Required: true})
|
||||
|
||||
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})
|
||||
|
||||
err := parser.Parse(os.Args)
|
||||
|
||||
if err != nil {
|
||||
@ -285,4 +321,12 @@ func main() {
|
||||
if putAliasCmd.Happened() {
|
||||
putAlias(client, *alias)
|
||||
}
|
||||
|
||||
if setServiceCmd.Happened() {
|
||||
setService(client, *serviceKey, *serviceValue)
|
||||
}
|
||||
|
||||
if deleteServiceCmd.Happened() {
|
||||
deleteService(client, *deleteServiceKey)
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ func meshNodeToAPIMeshNode(meshNode ctrlserver.MeshNode) *SmegNode {
|
||||
Description: meshNode.Description,
|
||||
Routes: meshNode.Routes,
|
||||
PublicKey: meshNode.PublicKey,
|
||||
Alias: meshNode.Alias,
|
||||
Services: meshNode.Services,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
package api
|
||||
|
||||
type SmegNode struct {
|
||||
WgHost string `json:"wgHost"`
|
||||
WgEndpoint string `json:"wgEndpoint"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Timestamp int `json:"timestamp"`
|
||||
Description string `json:"description"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
Routes []string `json:"routes"`
|
||||
Alias string `json:"alias"`
|
||||
WgHost string `json:"wgHost"`
|
||||
WgEndpoint string `json:"wgEndpoint"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Timestamp int `json:"timestamp"`
|
||||
Description string `json:"description"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
Routes []string `json:"routes"`
|
||||
Services map[string]string `json:"services"`
|
||||
}
|
||||
|
||||
type SmegMesh struct {
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
type CrdtMeshManager struct {
|
||||
MeshId string
|
||||
IfName string
|
||||
NodeId string
|
||||
Client *wgctrl.Client
|
||||
doc *automerge.Doc
|
||||
LastHash automerge.ChangeHash
|
||||
@ -35,8 +34,9 @@ func (c *CrdtMeshManager) AddNode(node mesh.MeshNode) {
|
||||
}
|
||||
|
||||
crdt.Routes = make(map[string]interface{})
|
||||
|
||||
crdt.Services = make(map[string]string)
|
||||
crdt.Timestamp = time.Now().Unix()
|
||||
|
||||
c.doc.Path("nodes").Map().Set(crdt.HostEndpoint, crdt)
|
||||
}
|
||||
|
||||
@ -198,6 +198,52 @@ func (m *CrdtMeshManager) SetAlias(nodeId string, alias string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *CrdtMeshManager) AddService(nodeId, key, value string) error {
|
||||
node, err := m.doc.Path("nodes").Map().Get(nodeId)
|
||||
|
||||
if err != nil || node.Kind() != automerge.KindMap {
|
||||
return fmt.Errorf("AddService: node %s does not exist", nodeId)
|
||||
}
|
||||
|
||||
service, err := node.Map().Get("services")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if service.Kind() != automerge.KindMap {
|
||||
return fmt.Errorf("AddService: services property does not exist in node")
|
||||
}
|
||||
|
||||
return service.Map().Set(key, value)
|
||||
}
|
||||
|
||||
func (m *CrdtMeshManager) RemoveService(nodeId, key string) error {
|
||||
node, err := m.doc.Path("nodes").Map().Get(nodeId)
|
||||
|
||||
if err != nil || node.Kind() != automerge.KindMap {
|
||||
return fmt.Errorf("RemoveService: node %s does not exist", nodeId)
|
||||
}
|
||||
|
||||
service, err := node.Map().Get("services")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if service.Kind() != automerge.KindMap {
|
||||
return fmt.Errorf("services property does not exist")
|
||||
}
|
||||
|
||||
err = service.Map().Delete(key)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %s does not exist", key)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRoutes: adds routes to the specific nodeId
|
||||
func (m *CrdtMeshManager) AddRoutes(nodeId string, routes ...string) error {
|
||||
nodeVal, err := m.doc.Path("nodes").Map().Get(nodeId)
|
||||
@ -360,6 +406,16 @@ func (m *MeshNodeCrdt) GetAlias() string {
|
||||
return m.Alias
|
||||
}
|
||||
|
||||
func (m *MeshNodeCrdt) GetServices() map[string]string {
|
||||
services := make(map[string]string)
|
||||
|
||||
for key, service := range m.Services {
|
||||
services[key] = service
|
||||
}
|
||||
|
||||
return services
|
||||
}
|
||||
|
||||
func (m *MeshCrdt) GetNodes() map[string]mesh.MeshNode {
|
||||
nodes := make(map[string]mesh.MeshNode)
|
||||
|
||||
@ -373,6 +429,7 @@ func (m *MeshCrdt) GetNodes() map[string]mesh.MeshNode {
|
||||
Routes: node.Routes,
|
||||
Description: node.Description,
|
||||
Alias: node.Alias,
|
||||
Services: node.GetServices(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ type MeshNodeCrdt struct {
|
||||
Routes map[string]interface{} `automerge:"routes"`
|
||||
Alias string `automerge:"alias"`
|
||||
Description string `automerge:"description"`
|
||||
Services map[string]string `automerge:"services"`
|
||||
}
|
||||
|
||||
// MeshCrdt: Represents the mesh network as a whole
|
||||
|
@ -18,6 +18,8 @@ type MeshNode struct {
|
||||
Timestamp int64
|
||||
Routes []string
|
||||
Description string
|
||||
Alias string
|
||||
Services map[string]string
|
||||
}
|
||||
|
||||
// Represents a WireGuard Mesh
|
||||
|
@ -17,34 +17,55 @@ const HOSTS_FILE = "/etc/hosts"
|
||||
const DOMAIN_HEADER = "#WG AUTO GENERATED HOSTS"
|
||||
const DOMAIN_TRAILER = "#WG AUTO GENERATED HOSTS END"
|
||||
|
||||
type HostsEntry struct {
|
||||
Alias string
|
||||
Ip net.IP
|
||||
}
|
||||
|
||||
// Generic interface to manipulate /etc/hosts file
|
||||
type HostsManipulator interface {
|
||||
// AddrAddr associates an aliasd with a given IP address
|
||||
AddAddr(ipAddr net.IP, alias string)
|
||||
AddAddr(hosts ...HostsEntry)
|
||||
// Remove deletes the entry from /etc/hosts
|
||||
Remove(alias string)
|
||||
Remove(hosts ...HostsEntry)
|
||||
// Writes the changes to /etc/hosts file
|
||||
Write() error
|
||||
}
|
||||
|
||||
type HostsManipulatorImpl struct {
|
||||
hosts map[string]net.IP
|
||||
meshid string
|
||||
hosts map[string]HostsEntry
|
||||
}
|
||||
|
||||
// AddAddr implements HostsManipulator.
|
||||
func (m *HostsManipulatorImpl) AddAddr(ipAddr net.IP, alias string) {
|
||||
m.hosts[alias] = ipAddr
|
||||
func (m *HostsManipulatorImpl) AddAddr(hosts ...HostsEntry) {
|
||||
changed := false
|
||||
|
||||
for _, host := range hosts {
|
||||
prev, ok := m.hosts[host.Ip.String()]
|
||||
|
||||
if !ok || prev.Alias != host.Alias {
|
||||
changed = true
|
||||
}
|
||||
|
||||
m.hosts[host.Ip.String()] = host
|
||||
}
|
||||
|
||||
if changed {
|
||||
m.Write()
|
||||
}
|
||||
}
|
||||
|
||||
// Remove implements HostsManipulator.
|
||||
func (m *HostsManipulatorImpl) Remove(alias string) {
|
||||
delete(m.hosts, alias)
|
||||
}
|
||||
func (m *HostsManipulatorImpl) Remove(hosts ...HostsEntry) {
|
||||
lenBefore := len(m.hosts)
|
||||
|
||||
type HostsEntry struct {
|
||||
Alias string
|
||||
Ip net.IP
|
||||
for _, host := range hosts {
|
||||
delete(m.hosts, host.Alias)
|
||||
}
|
||||
|
||||
if lenBefore != len(m.hosts) {
|
||||
m.Write()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *HostsManipulatorImpl) removeHosts() string {
|
||||
@ -69,7 +90,7 @@ func (m *HostsManipulatorImpl) removeHosts() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
if !hostsSection && strings.Contains(line, DOMAIN_HEADER+m.meshid) {
|
||||
if !hostsSection && strings.Contains(line, DOMAIN_HEADER) {
|
||||
hostsSection = true
|
||||
}
|
||||
|
||||
@ -77,7 +98,7 @@ func (m *HostsManipulatorImpl) removeHosts() string {
|
||||
contents.WriteString(line + "\n")
|
||||
}
|
||||
|
||||
if hostsSection && strings.Contains(line, DOMAIN_TRAILER+m.meshid) {
|
||||
if hostsSection && strings.Contains(line, DOMAIN_TRAILER) {
|
||||
hostsSection = false
|
||||
}
|
||||
}
|
||||
@ -96,36 +117,16 @@ func (m *HostsManipulatorImpl) Write() error {
|
||||
var nextHosts strings.Builder
|
||||
nextHosts.WriteString(contents)
|
||||
|
||||
nextHosts.WriteString(DOMAIN_HEADER + m.meshid + "\n")
|
||||
nextHosts.WriteString(DOMAIN_HEADER + "\n")
|
||||
|
||||
for alias, ip := range m.hosts {
|
||||
nextHosts.WriteString(fmt.Sprintf("%s\t%s\n", ip.String(), alias))
|
||||
for _, host := range m.hosts {
|
||||
nextHosts.WriteString(fmt.Sprintf("%s\t%s\n", host.Ip.String(), host.Alias))
|
||||
}
|
||||
|
||||
nextHosts.WriteString(DOMAIN_TRAILER + m.meshid + "\n")
|
||||
nextHosts.WriteString(DOMAIN_TRAILER + "\n")
|
||||
return os.WriteFile(HOSTS_FILE, []byte(nextHosts.String()), 0644)
|
||||
}
|
||||
|
||||
// parseLine parses a line in the /etc/hosts file
|
||||
func parseLine(line string) (*HostsEntry, error) {
|
||||
fields := strings.Fields(line)
|
||||
|
||||
if len(fields) != 2 {
|
||||
return nil, fmt.Errorf("expected entry length of 2 was %d", len(fields))
|
||||
}
|
||||
|
||||
ipAddr := fields[0]
|
||||
alias := fields[1]
|
||||
|
||||
ip := net.ParseIP(ipAddr)
|
||||
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("failed to parse ip for %s", alias)
|
||||
}
|
||||
|
||||
return &HostsEntry{Ip: ip, Alias: alias}, nil
|
||||
}
|
||||
|
||||
func NewHostsManipulator(meshId string) HostsManipulator {
|
||||
return &HostsManipulatorImpl{hosts: make(map[string]net.IP), meshid: meshId}
|
||||
func NewHostsManipulator() HostsManipulator {
|
||||
return &HostsManipulatorImpl{hosts: make(map[string]HostsEntry)}
|
||||
}
|
||||
|
@ -34,6 +34,11 @@ type JoinMeshArgs struct {
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
type PutServiceArgs struct {
|
||||
Service string
|
||||
Value string
|
||||
}
|
||||
|
||||
type GetMeshReply struct {
|
||||
Nodes []ctrlserver.MeshNode
|
||||
}
|
||||
@ -58,6 +63,8 @@ type MeshIpc interface {
|
||||
Query(query QueryMesh, reply *string) error
|
||||
PutDescription(description string, reply *string) error
|
||||
PutAlias(alias string, reply *string) error
|
||||
PutService(args PutServiceArgs, reply *string) error
|
||||
DeleteService(service string, reply *string) error
|
||||
}
|
||||
|
||||
const SockAddr = "/tmp/wgmesh_ipc.sock"
|
||||
|
@ -1,15 +1,46 @@
|
||||
package mesh
|
||||
|
||||
import "github.com/tim-beatham/wgmesh/pkg/hosts"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
func AddAliases(meshid string, snapshot MeshSnapshot) {
|
||||
hosts := hosts.NewHostsManipulator(meshid)
|
||||
"github.com/tim-beatham/wgmesh/pkg/hosts"
|
||||
)
|
||||
|
||||
for _, node := range snapshot.GetNodes() {
|
||||
type MeshAliasManager interface {
|
||||
AddAliases(nodes []MeshNode)
|
||||
RemoveAliases(node []MeshNode)
|
||||
}
|
||||
|
||||
type AliasManager struct {
|
||||
hosts hosts.HostsManipulator
|
||||
}
|
||||
|
||||
// AddAliases: on node update or change add aliases to the hosts file
|
||||
func (a *AliasManager) AddAliases(nodes []MeshNode) {
|
||||
for _, node := range nodes {
|
||||
if node.GetAlias() != "" {
|
||||
hosts.AddAddr(node.GetWgHost().IP, node.GetAlias())
|
||||
a.hosts.AddAddr(hosts.HostsEntry{
|
||||
Alias: fmt.Sprintf("%s.smeg", node.GetAlias()),
|
||||
Ip: node.GetWgHost().IP,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
hosts.Write()
|
||||
}
|
||||
|
||||
// RemoveAliases: on node remove remove aliases from the hosts file
|
||||
func (a *AliasManager) RemoveAliases(nodes []MeshNode) {
|
||||
for _, node := range nodes {
|
||||
if node.GetAlias() != "" {
|
||||
a.hosts.Remove(hosts.HostsEntry{
|
||||
Alias: fmt.Sprintf("%s.smeg", node.GetAlias()),
|
||||
Ip: node.GetWgHost().IP,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewAliasManager() MeshAliasManager {
|
||||
return &AliasManager{
|
||||
hosts: hosts.NewHostsManipulator(),
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ type MeshManager interface {
|
||||
ApplyConfig() error
|
||||
SetDescription(description string) error
|
||||
SetAlias(alias string) error
|
||||
SetService(service string, value string) error
|
||||
RemoveService(service string) error
|
||||
UpdateTimeStamp() error
|
||||
GetClient() *wgctrl.Client
|
||||
GetMeshes() map[string]MeshProvider
|
||||
@ -51,6 +53,32 @@ type MeshManagerImpl struct {
|
||||
Monitor MeshMonitor
|
||||
}
|
||||
|
||||
// RemoveService implements MeshManager.
|
||||
func (m *MeshManagerImpl) RemoveService(service string) error {
|
||||
for _, mesh := range m.Meshes {
|
||||
err := mesh.RemoveService(m.HostParameters.HostEndpoint, service)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetService implements MeshManager.
|
||||
func (m *MeshManagerImpl) SetService(service string, value string) error {
|
||||
for _, mesh := range m.Meshes {
|
||||
err := mesh.AddService(m.HostParameters.HostEndpoint, service, value)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMonitor implements MeshManager.
|
||||
func (m *MeshManagerImpl) GetMonitor() MeshMonitor {
|
||||
return m.Monitor
|
||||
@ -411,7 +439,10 @@ func NewMeshManager(params *NewMeshManagerParams) MeshManager {
|
||||
m.ipAllocator = params.IPAllocator
|
||||
m.interfaceManipulator = params.InterfaceManipulator
|
||||
|
||||
m.Monitor = NewMeshMonitor()
|
||||
m.Monitor.AddCallback(AddAliases)
|
||||
m.Monitor = NewMeshMonitor(m)
|
||||
|
||||
aliasManager := NewAliasManager()
|
||||
m.Monitor.AddUpdateCallback(aliasManager.AddAliases)
|
||||
m.Monitor.AddRemoveCallback(aliasManager.RemoveAliases)
|
||||
return m
|
||||
}
|
||||
|
@ -1,28 +1,81 @@
|
||||
package mesh
|
||||
|
||||
type OnChange = func(string, MeshSnapshot)
|
||||
type OnChange = func([]MeshNode)
|
||||
|
||||
type MeshMonitor interface {
|
||||
AddCallback(cb OnChange)
|
||||
Trigger(meshid string, m MeshSnapshot)
|
||||
AddUpdateCallback(cb OnChange)
|
||||
AddRemoveCallback(cb OnChange)
|
||||
Trigger() error
|
||||
}
|
||||
|
||||
type MeshMonitorImpl struct {
|
||||
callbacks []OnChange
|
||||
updateCbs []OnChange
|
||||
removeCbs []OnChange
|
||||
nodes map[string]MeshNode
|
||||
manager MeshManager
|
||||
}
|
||||
|
||||
func (m *MeshMonitorImpl) Trigger(meshid string, snapshot MeshSnapshot) {
|
||||
for _, cb := range m.callbacks {
|
||||
cb(meshid, snapshot)
|
||||
// Trigger causes the mesh monitor to trigger all of
|
||||
// the callbacks.
|
||||
func (m *MeshMonitorImpl) Trigger() error {
|
||||
changedNodes := make([]MeshNode, 0)
|
||||
removedNodes := make([]MeshNode, 0)
|
||||
|
||||
nodes := make(map[string]MeshNode)
|
||||
|
||||
for _, mesh := range m.manager.GetMeshes() {
|
||||
snapshot, err := mesh.GetMesh()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, node := range snapshot.GetNodes() {
|
||||
previous, exists := m.nodes[node.GetWgHost().String()]
|
||||
|
||||
if !exists || !NodeEquals(previous, node) {
|
||||
changedNodes = append(changedNodes, node)
|
||||
}
|
||||
|
||||
nodes[node.GetWgHost().String()] = node
|
||||
}
|
||||
}
|
||||
|
||||
for _, previous := range m.nodes {
|
||||
_, ok := nodes[previous.GetWgHost().String()]
|
||||
|
||||
if !ok {
|
||||
removedNodes = append(removedNodes, previous)
|
||||
}
|
||||
}
|
||||
|
||||
if len(removedNodes) > 0 {
|
||||
for _, cb := range m.removeCbs {
|
||||
cb(removedNodes)
|
||||
}
|
||||
}
|
||||
|
||||
if len(changedNodes) > 0 {
|
||||
for _, cb := range m.updateCbs {
|
||||
cb(changedNodes)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MeshMonitorImpl) AddCallback(cb OnChange) {
|
||||
m.callbacks = append(m.callbacks, cb)
|
||||
func (m *MeshMonitorImpl) AddUpdateCallback(cb OnChange) {
|
||||
m.updateCbs = append(m.updateCbs, cb)
|
||||
}
|
||||
|
||||
func NewMeshMonitor() MeshMonitor {
|
||||
func (m *MeshMonitorImpl) AddRemoveCallback(cb OnChange) {
|
||||
m.removeCbs = append(m.removeCbs, cb)
|
||||
}
|
||||
|
||||
func NewMeshMonitor(manager MeshManager) MeshMonitor {
|
||||
return &MeshMonitorImpl{
|
||||
callbacks: make([]OnChange, 0),
|
||||
updateCbs: make([]OnChange, 0),
|
||||
nodes: make(map[string]MeshNode),
|
||||
manager: manager,
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,14 @@ type MeshNodeStub struct {
|
||||
description string
|
||||
}
|
||||
|
||||
// GetServices implements MeshNode.
|
||||
func (*MeshNodeStub) GetServices() map[string]string {
|
||||
return make(map[string]string)
|
||||
}
|
||||
|
||||
// GetAlias implements MeshNode.
|
||||
func (*MeshNodeStub) GetAlias() string {
|
||||
panic("unimplemented")
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *MeshNodeStub) GetHostEndpoint() string {
|
||||
@ -71,6 +76,16 @@ type MeshProviderStub struct {
|
||||
snapshot *MeshSnapshotStub
|
||||
}
|
||||
|
||||
// AddService implements MeshProvider.
|
||||
func (*MeshProviderStub) AddService(nodeId string, key string, value string) error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// RemoveService implements MeshProvider.
|
||||
func (*MeshProviderStub) RemoveService(nodeId string, key string) error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// SetAlias implements MeshProvider.
|
||||
func (*MeshProviderStub) SetAlias(nodeId string, alias string) error {
|
||||
panic("unimplemented")
|
||||
@ -181,6 +196,16 @@ type MeshManagerStub struct {
|
||||
meshes map[string]MeshProvider
|
||||
}
|
||||
|
||||
// RemoveService implements MeshManager.
|
||||
func (*MeshManagerStub) RemoveService(service string) error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// SetService implements MeshManager.
|
||||
func (*MeshManagerStub) SetService(service string, value string) error {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// GetMonitor implements MeshManager.
|
||||
func (*MeshManagerStub) GetMonitor() MeshMonitor {
|
||||
panic("unimplemented")
|
||||
|
@ -4,6 +4,7 @@ package mesh
|
||||
|
||||
import (
|
||||
"net"
|
||||
"slices"
|
||||
|
||||
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
@ -31,6 +32,48 @@ type MeshNode interface {
|
||||
// GetAlias: associates the node with an alias. Potentially used
|
||||
// for DNS and so forth.
|
||||
GetAlias() string
|
||||
// GetServices: returns a list of services offered by the node
|
||||
GetServices() map[string]string
|
||||
}
|
||||
|
||||
// NodeEquals: determines if two mesh nodes are equivalent to one another
|
||||
func NodeEquals(node1, node2 MeshNode) bool {
|
||||
if node1.GetHostEndpoint() != node2.GetHostEndpoint() {
|
||||
return false
|
||||
}
|
||||
|
||||
node1Pub, _ := node1.GetPublicKey()
|
||||
node2Pub, _ := node2.GetPublicKey()
|
||||
|
||||
if node1Pub != node2Pub {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetWgEndpoint() != node2.GetWgEndpoint() {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetWgHost() != node2.GetWgHost() {
|
||||
return false
|
||||
}
|
||||
|
||||
if !slices.Equal(node1.GetRoutes(), node2.GetRoutes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetIdentifier() != node2.GetIdentifier() {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetDescription() != node2.GetDescription() {
|
||||
return false
|
||||
}
|
||||
|
||||
if node1.GetAlias() != node2.GetAlias() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type MeshSnapshot interface {
|
||||
@ -75,6 +118,10 @@ type MeshProvider interface {
|
||||
SetDescription(nodeId string, description string) error
|
||||
// SetAlias: set the alias of the nodeId
|
||||
SetAlias(nodeId string, alias string) error
|
||||
// AddService: adds the service to the given node
|
||||
AddService(nodeId, key, value string) error
|
||||
// RemoveService: removes the service form the node. throws an error if the service does not exist
|
||||
RemoveService(nodeId, key string) error
|
||||
// Prune: prunes all nodes that have not updated their timestamp in
|
||||
// pruneAmount seconds
|
||||
Prune(pruneAmount int) error
|
||||
|
@ -24,14 +24,15 @@ type QueryError struct {
|
||||
}
|
||||
|
||||
type QueryNode struct {
|
||||
HostEndpoint string `json:"hostEndpoint"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
WgEndpoint string `json:"wgEndpoint"`
|
||||
WgHost string `json:"wgHost"`
|
||||
Timestamp int64 `json:"timestmap"`
|
||||
Description string `json:"description"`
|
||||
Routes []string `json:"routes"`
|
||||
Alias string `json:"alias"`
|
||||
HostEndpoint string `json:"hostEndpoint"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
WgEndpoint string `json:"wgEndpoint"`
|
||||
WgHost string `json:"wgHost"`
|
||||
Timestamp int64 `json:"timestmap"`
|
||||
Description string `json:"description"`
|
||||
Routes []string `json:"routes"`
|
||||
Alias string `json:"alias"`
|
||||
Services map[string]string `json:"services"`
|
||||
}
|
||||
|
||||
func (m *QueryError) Error() string {
|
||||
@ -78,6 +79,7 @@ func meshNodeToQueryNode(node mesh.MeshNode) *QueryNode {
|
||||
queryNode.Routes = node.GetRoutes()
|
||||
queryNode.Description = node.GetDescription()
|
||||
queryNode.Alias = node.GetAlias()
|
||||
queryNode.Services = node.GetServices()
|
||||
|
||||
return queryNode
|
||||
}
|
||||
|
@ -117,6 +117,11 @@ func (n *IpcHandler) LeaveMesh(meshId string, reply *string) error {
|
||||
|
||||
func (n *IpcHandler) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
|
||||
mesh := n.Server.GetMeshManager().GetMesh(meshId)
|
||||
|
||||
if mesh == nil {
|
||||
return fmt.Errorf("mesh %s does not exist", meshId)
|
||||
}
|
||||
|
||||
meshSnapshot, err := mesh.GetMesh()
|
||||
|
||||
if err != nil {
|
||||
@ -145,6 +150,8 @@ func (n *IpcHandler) GetMesh(meshId string, reply *ipc.GetMeshReply) error {
|
||||
Timestamp: node.GetTimeStamp(),
|
||||
Routes: node.GetRoutes(),
|
||||
Description: node.GetDescription(),
|
||||
Alias: node.GetAlias(),
|
||||
Services: node.GetServices(),
|
||||
}
|
||||
|
||||
nodes[i] = node
|
||||
@ -213,6 +220,28 @@ func (n *IpcHandler) PutAlias(alias string, reply *string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *IpcHandler) PutService(service ipc.PutServiceArgs, reply *string) error {
|
||||
err := n.Server.GetMeshManager().SetService(service.Service, service.Value)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*reply = "success"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *IpcHandler) DeleteService(service string, reply *string) error {
|
||||
err := n.Server.GetMeshManager().RemoveService(service)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*reply = "success"
|
||||
return nil
|
||||
}
|
||||
|
||||
type RobinIpcParams struct {
|
||||
CtrlServer ctrlserver.CtrlServer
|
||||
}
|
||||
|
@ -48,14 +48,7 @@ func (s *SyncerImpl) Sync(meshId string) error {
|
||||
return errors.New("the provided mesh does not exist")
|
||||
}
|
||||
|
||||
snapshot, err := theMesh.GetMesh()
|
||||
|
||||
s.manager.GetMonitor().Trigger(meshId, snapshot)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
snapshot, _ := theMesh.GetMesh()
|
||||
nodes := snapshot.GetNodes()
|
||||
|
||||
if len(nodes) <= 1 {
|
||||
@ -109,24 +102,19 @@ func (s *SyncerImpl) Sync(meshId string) error {
|
||||
waitGroup.Wait()
|
||||
|
||||
s.syncCount++
|
||||
logging.Log.WriteInfof("SYNC TIME: %v", time.Now().Sub(before))
|
||||
logging.Log.WriteInfof("SYNC TIME: %v", time.Since(before))
|
||||
logging.Log.WriteInfof("SYNC COUNT: %d", s.syncCount)
|
||||
|
||||
s.infectionCount = ((s.conf.InfectionCount + s.infectionCount - 1) % s.conf.InfectionCount)
|
||||
|
||||
newMesh := s.manager.GetMesh(meshId)
|
||||
snapshot, err = newMesh.GetMesh()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
// Check if any changes have occurred and trigger callbacks
|
||||
// if changes have occurred.
|
||||
return s.manager.GetMonitor().Trigger()
|
||||
}
|
||||
|
||||
// SyncMeshes: Sync all meshes
|
||||
func (s *SyncerImpl) SyncMeshes() error {
|
||||
for meshId, _ := range s.manager.GetMeshes() {
|
||||
for meshId := range s.manager.GetMeshes() {
|
||||
err := s.Sync(meshId)
|
||||
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user