forked from extern/smegmesh
Few refactorings of managing the mesh and a graph
visualisation tool for seeing the state of a mesh.
This commit is contained in:
parent
c4dc984fc7
commit
360f9d3c54
@ -87,6 +87,19 @@ func enableInterface(client *ipcRpc.Client, meshId string) {
|
|||||||
fmt.Println(reply)
|
fmt.Println(reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGraph(client *ipcRpc.Client, meshId string) {
|
||||||
|
var reply string
|
||||||
|
|
||||||
|
err := client.Call("RobinIpc.GetDOT", &meshId, &reply)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(reply)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
parser := argparse.NewParser("wg-mesh",
|
parser := argparse.NewParser("wg-mesh",
|
||||||
"wg-mesh Manipulate WireGuard meshes")
|
"wg-mesh Manipulate WireGuard meshes")
|
||||||
@ -96,12 +109,13 @@ func main() {
|
|||||||
joinMeshCmd := parser.NewCommand("join-mesh", "Join a mesh network")
|
joinMeshCmd := parser.NewCommand("join-mesh", "Join a mesh network")
|
||||||
getMeshCmd := parser.NewCommand("get-mesh", "Get a mesh network")
|
getMeshCmd := parser.NewCommand("get-mesh", "Get a mesh network")
|
||||||
enableInterfaceCmd := parser.NewCommand("enable-interface", "Enable A Specific Mesh Interface")
|
enableInterfaceCmd := parser.NewCommand("enable-interface", "Enable A Specific Mesh Interface")
|
||||||
|
getGraphCmd := parser.NewCommand("get-graph", "Convert a mesh into DOT format")
|
||||||
|
|
||||||
var meshId *string = joinMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
var meshId *string = joinMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
||||||
var ipAddress *string = joinMeshCmd.String("i", "ip", &argparse.Options{Required: true})
|
var ipAddress *string = joinMeshCmd.String("i", "ip", &argparse.Options{Required: true})
|
||||||
|
|
||||||
var getMeshId *string = getMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
var getMeshId *string = getMeshCmd.String("m", "mesh", &argparse.Options{Required: true})
|
||||||
var enableInterfaceMeshId *string = enableInterfaceCmd.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})
|
||||||
|
|
||||||
err := parser.Parse(os.Args)
|
err := parser.Parse(os.Args)
|
||||||
|
|
||||||
@ -132,6 +146,10 @@ func main() {
|
|||||||
getMesh(client, *getMeshId)
|
getMesh(client, *getMeshId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if getGraphCmd.Happened() {
|
||||||
|
getGraph(client, *getGraphMeshId)
|
||||||
|
}
|
||||||
|
|
||||||
if enableInterfaceCmd.Happened() {
|
if enableInterfaceCmd.Happened() {
|
||||||
enableInterface(client, *enableInterfaceMeshId)
|
enableInterface(client, *enableInterfaceMeshId)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package crdt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -188,13 +189,13 @@ func (m *CrdtNodeManager) GetNode(endpoint string) (*MeshNodeCrdt, error) {
|
|||||||
return meshNode, nil
|
return meshNode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const threshold = 2
|
|
||||||
const thresholdVotes = 0.1
|
|
||||||
|
|
||||||
func (m *CrdtNodeManager) Length() int {
|
func (m *CrdtNodeManager) Length() int {
|
||||||
return m.doc.Path("nodes").Map().Len()
|
return m.doc.Path("nodes").Map().Len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const threshold = 2
|
||||||
|
const thresholdVotes = 0.1
|
||||||
|
|
||||||
func (m *CrdtNodeManager) HasFailed(endpoint string) bool {
|
func (m *CrdtNodeManager) HasFailed(endpoint string) bool {
|
||||||
node, err := m.GetNode(endpoint)
|
node, err := m.GetNode(endpoint)
|
||||||
|
|
||||||
@ -249,3 +250,7 @@ func (m *CrdtNodeManager) updateWgConf(devName string, nodes map[string]MeshNode
|
|||||||
client.ConfigureDevice(devName, cfg)
|
client.ConfigureDevice(devName, cfg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *MeshNodeCrdt) GetEscapedIP() string {
|
||||||
|
return fmt.Sprintf("\"%s\"", n.WgHost)
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@ package ctrlserver
|
|||||||
import (
|
import (
|
||||||
"github.com/tim-beatham/wgmesh/pkg/conf"
|
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/conn"
|
"github.com/tim-beatham/wgmesh/pkg/conn"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/manager"
|
"github.com/tim-beatham/wgmesh/pkg/mesh"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/rpc"
|
"github.com/tim-beatham/wgmesh/pkg/rpc"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
)
|
)
|
||||||
@ -30,7 +30,7 @@ type NewCtrlServerParams struct {
|
|||||||
func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
|
func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
|
||||||
ctrlServer := new(MeshCtrlServer)
|
ctrlServer := new(MeshCtrlServer)
|
||||||
ctrlServer.Client = params.WgClient
|
ctrlServer.Client = params.WgClient
|
||||||
ctrlServer.MeshManager = manager.NewMeshManager(*params.WgClient, *params.Conf)
|
ctrlServer.MeshManager = mesh.NewMeshManager(*params.WgClient, *params.Conf)
|
||||||
ctrlServer.Conf = params.Conf
|
ctrlServer.Conf = params.Conf
|
||||||
|
|
||||||
connManagerParams := conn.NewJwtConnectionManagerParams{
|
connManagerParams := conn.NewJwtConnectionManagerParams{
|
||||||
|
@ -3,7 +3,7 @@ package ctrlserver
|
|||||||
import (
|
import (
|
||||||
"github.com/tim-beatham/wgmesh/pkg/conf"
|
"github.com/tim-beatham/wgmesh/pkg/conf"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/conn"
|
"github.com/tim-beatham/wgmesh/pkg/conn"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/manager"
|
"github.com/tim-beatham/wgmesh/pkg/mesh"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
)
|
)
|
||||||
@ -30,7 +30,7 @@ type Mesh struct {
|
|||||||
*/
|
*/
|
||||||
type MeshCtrlServer struct {
|
type MeshCtrlServer struct {
|
||||||
Client *wgctrl.Client
|
Client *wgctrl.Client
|
||||||
MeshManager *manager.MeshManger
|
MeshManager *mesh.MeshManger
|
||||||
ConnectionManager conn.ConnectionManager
|
ConnectionManager conn.ConnectionManager
|
||||||
ConnectionServer *conn.ConnectionServer
|
ConnectionServer *conn.ConnectionServer
|
||||||
Conf *conf.WgMeshConfiguration
|
Conf *conf.WgMeshConfiguration
|
||||||
|
169
pkg/graph/graph.go
Normal file
169
pkg/graph/graph.go
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Graph allows the definition of a DOT graph in golang
|
||||||
|
package graph
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GraphType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
GRAPH GraphType = "graph"
|
||||||
|
DIGRAPH = "digraph"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Graph struct {
|
||||||
|
Type GraphType
|
||||||
|
Label string
|
||||||
|
nodes map[string]*Node
|
||||||
|
edges []Edge
|
||||||
|
}
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Edge interface {
|
||||||
|
Dottable
|
||||||
|
}
|
||||||
|
|
||||||
|
type DirectedEdge struct {
|
||||||
|
Label string
|
||||||
|
From *Node
|
||||||
|
To *Node
|
||||||
|
}
|
||||||
|
|
||||||
|
type UndirectedEdge struct {
|
||||||
|
Label string
|
||||||
|
From *Node
|
||||||
|
To *Node
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dottable means an implementer can convert the struct to DOT representation
|
||||||
|
type Dottable interface {
|
||||||
|
GetDOT() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGraph(label string, graphType GraphType) *Graph {
|
||||||
|
return &Graph{Type: graphType, Label: label, nodes: make(map[string]*Node), edges: make([]Edge, 0)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNode: adds a node to the graph
|
||||||
|
func (g *Graph) AddNode(label string) error {
|
||||||
|
_, exists := g.nodes[label]
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
return errors.New(fmt.Sprintf("Node %s already exists", label))
|
||||||
|
}
|
||||||
|
|
||||||
|
g.nodes[label] = &Node{Name: label}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeContituents[D Dottable](result *strings.Builder, elements ...D) error {
|
||||||
|
for _, node := range elements {
|
||||||
|
dot, err := node.GetDOT()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = result.WriteString(dot)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Graph) GetDOT() (string, error) {
|
||||||
|
var result strings.Builder
|
||||||
|
|
||||||
|
_, err := result.WriteString(fmt.Sprintf("%s {\n", g.Type))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = result.WriteString("node [colorscheme=set312];\n")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes := lib.MapValues(g.nodes)
|
||||||
|
|
||||||
|
err = writeContituents(&result, nodes...)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = writeContituents(&result, g.edges...)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = result.WriteString("}")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Graph) constructEdge(label string, from *Node, to *Node) Edge {
|
||||||
|
switch g.Type {
|
||||||
|
case DIGRAPH:
|
||||||
|
return &DirectedEdge{Label: label, From: from, To: to}
|
||||||
|
default:
|
||||||
|
return &UndirectedEdge{Label: label, From: from, To: to}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddEdge: adds an edge between two nodes in the graph
|
||||||
|
func (g *Graph) AddEdge(label string, from string, to string) error {
|
||||||
|
fromNode, exists := g.nodes[from]
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return errors.New(fmt.Sprintf("Node %s does not exist", from))
|
||||||
|
}
|
||||||
|
|
||||||
|
toNode, exists := g.nodes[to]
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return errors.New(fmt.Sprintf("Node %s does not exist", to))
|
||||||
|
}
|
||||||
|
|
||||||
|
g.edges = append(g.edges, g.constructEdge(label, fromNode, toNode))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const numColours = 12
|
||||||
|
|
||||||
|
func (n *Node) hash() int {
|
||||||
|
h := fnv.New32a()
|
||||||
|
h.Write([]byte(n.Name))
|
||||||
|
return (int(h.Sum32()) % numColours) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) GetDOT() (string, error) {
|
||||||
|
return fmt.Sprintf("node[shape=circle, style=\"filled\", fillcolor=%d] %s;\n",
|
||||||
|
n.hash(), n.Name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *DirectedEdge) GetDOT() (string, error) {
|
||||||
|
return fmt.Sprintf("%s -> %s;\n", e.From.Name, e.To.Name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UndirectedEdge) GetDOT() (string, error) {
|
||||||
|
return fmt.Sprintf("%s -- %s;\n", e.From.Name, e.To.Name), nil
|
||||||
|
}
|
@ -29,6 +29,7 @@ type MeshIpc interface {
|
|||||||
JoinMesh(args JoinMeshArgs, reply *string) error
|
JoinMesh(args JoinMeshArgs, reply *string) error
|
||||||
GetMesh(meshId string, reply *GetMeshReply) error
|
GetMesh(meshId string, reply *GetMeshReply) error
|
||||||
EnableInterface(meshId string, reply *string) error
|
EnableInterface(meshId string, reply *string) error
|
||||||
|
GetDOT(meshId string, reply *string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
const SockAddr = "/tmp/wgmesh_ipc.sock"
|
const SockAddr = "/tmp/wgmesh_ipc.sock"
|
||||||
|
60
pkg/mesh/graph_generator.go
Normal file
60
pkg/mesh/graph_generator.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package mesh
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tim-beatham/wgmesh/pkg/graph"
|
||||||
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MeshGraphConverter interface {
|
||||||
|
// convert the mesh to textual form
|
||||||
|
Generate(meshId string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MeshDOTConverter struct {
|
||||||
|
manager *MeshManger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MeshDOTConverter) Generate(meshId string) (string, error) {
|
||||||
|
mesh := c.manager.GetMesh(meshId)
|
||||||
|
|
||||||
|
if mesh == nil {
|
||||||
|
return "", errors.New("mesh does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
g := graph.NewGraph(meshId, graph.GRAPH)
|
||||||
|
|
||||||
|
snapshot, err := mesh.GetCrdt()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node := range snapshot.Nodes {
|
||||||
|
g.AddNode(node.GetEscapedIP())
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes := lib.MapValues(snapshot.Nodes)
|
||||||
|
|
||||||
|
for i, node1 := range nodes[:len(nodes)-1] {
|
||||||
|
if mesh.HasFailed(node1.HostEndpoint) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node2 := range nodes[i+1:] {
|
||||||
|
if node1 == node2 || mesh.HasFailed(node2.HostEndpoint) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
g.AddEdge(fmt.Sprintf("%s to %s", node1.GetEscapedIP(), node2.GetEscapedIP()), node1.GetEscapedIP(), node2.GetEscapedIP())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g.GetDOT()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMeshDotConverter(m *MeshManger) MeshGraphConverter {
|
||||||
|
return &MeshDOTConverter{manager: m}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package manager
|
package mesh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/tim-beatham/wgmesh/pkg/ipc"
|
"github.com/tim-beatham/wgmesh/pkg/ipc"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||||
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
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/rpc"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/wg"
|
"github.com/tim-beatham/wgmesh/pkg/wg"
|
||||||
)
|
)
|
||||||
@ -261,6 +262,19 @@ func (n *RobinIpc) EnableInterface(meshId string, reply *string) error {
|
|||||||
return nil
|
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 {
|
type RobinIpcParams struct {
|
||||||
CtrlServer *ctrlserver.MeshCtrlServer
|
CtrlServer *ctrlserver.MeshCtrlServer
|
||||||
Allocator ip.IPAllocator
|
Allocator ip.IPAllocator
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
|
|
||||||
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/manager"
|
"github.com/tim-beatham/wgmesh/pkg/mesh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Syncer: picks random nodes from the mesh
|
// Syncer: picks random nodes from the mesh
|
||||||
@ -15,7 +15,7 @@ type Syncer interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SyncerImpl struct {
|
type SyncerImpl struct {
|
||||||
manager *manager.MeshManger
|
manager *mesh.MeshManger
|
||||||
requester SyncRequester
|
requester SyncRequester
|
||||||
authenticatedNodes []crdt.MeshNodeCrdt
|
authenticatedNodes []crdt.MeshNodeCrdt
|
||||||
}
|
}
|
||||||
@ -45,6 +45,12 @@ func (s *SyncerImpl) Sync(meshId string) error {
|
|||||||
s.manager.HostEndpoint: {},
|
s.manager.HostEndpoint: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, node := range snapshot.Nodes {
|
||||||
|
if mesh.HasFailed(node.HostEndpoint) {
|
||||||
|
excludedNodes[node.HostEndpoint] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
meshNodes := lib.MapValuesWithExclude(snapshot.Nodes, excludedNodes)
|
meshNodes := lib.MapValuesWithExclude(snapshot.Nodes, excludedNodes)
|
||||||
randomSubset := lib.RandomSubsetOfLength(meshNodes, subSetLength)
|
randomSubset := lib.RandomSubsetOfLength(meshNodes, subSetLength)
|
||||||
|
|
||||||
@ -72,6 +78,6 @@ func (s *SyncerImpl) SyncMeshes() error {
|
|||||||
return s.manager.ApplyWg()
|
return s.manager.ApplyWg()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncer(m *manager.MeshManger, r SyncRequester) Syncer {
|
func NewSyncer(m *mesh.MeshManger, r SyncRequester) Syncer {
|
||||||
return &SyncerImpl{manager: m, requester: r}
|
return &SyncerImpl{manager: m, requester: r}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package sync
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
||||||
"github.com/tim-beatham/wgmesh/pkg/manager"
|
"github.com/tim-beatham/wgmesh/pkg/mesh"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
@ -12,7 +12,7 @@ type SyncErrorHandler interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SyncErrorHandlerImpl struct {
|
type SyncErrorHandlerImpl struct {
|
||||||
meshManager *manager.MeshManger
|
meshManager *mesh.MeshManger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SyncErrorHandlerImpl) incrementFailedCount(meshId string, endpoint string) bool {
|
func (s *SyncErrorHandlerImpl) incrementFailedCount(meshId string, endpoint string) bool {
|
||||||
@ -44,6 +44,6 @@ func (s *SyncErrorHandlerImpl) Handle(meshId string, endpoint string, err error)
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncErrorHandler(m *manager.MeshManger) SyncErrorHandler {
|
func NewSyncErrorHandler(m *mesh.MeshManger) SyncErrorHandler {
|
||||||
return &SyncErrorHandlerImpl{meshManager: m}
|
return &SyncErrorHandlerImpl{meshManager: m}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user