Implement node function as type functions
This means nodeMeta can be private again, and also makes it easier to pass a Node object to the cluster for local meta, instead of a generic byte[] function. For later updating, that node is passed using Update() instead of New().
This commit is contained in:
parent
dadfbee083
commit
46da51b7aa
|
@ -28,14 +28,14 @@ type State struct {
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
LocalName string // used to avoid LocalNode(); should not change
|
LocalName string // used to avoid LocalNode(); should not change
|
||||||
ml *memberlist.Memberlist
|
ml *memberlist.Memberlist
|
||||||
getMeta func(int) []byte
|
localNode common.Node
|
||||||
state *State
|
state *State
|
||||||
events chan memberlist.NodeEvent
|
events chan memberlist.NodeEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
const statePath = "/var/lib/wesher/state.json"
|
const statePath = "/var/lib/wesher/state.json"
|
||||||
|
|
||||||
func New(init bool, clusterKey []byte, bindAddr string, bindPort int, useIPAsName bool, getMeta func(int) []byte) (*Cluster, error) {
|
func New(init bool, clusterKey []byte, bindAddr string, bindPort int, useIPAsName bool) (*Cluster, error) {
|
||||||
state := &State{}
|
state := &State{}
|
||||||
if !init {
|
if !init {
|
||||||
loadState(state)
|
loadState(state)
|
||||||
|
@ -64,7 +64,6 @@ func New(init bool, clusterKey []byte, bindAddr string, bindPort int, useIPAsNam
|
||||||
cluster := Cluster{
|
cluster := Cluster{
|
||||||
LocalName: ml.LocalNode().Name,
|
LocalName: ml.LocalNode().Name,
|
||||||
ml: ml,
|
ml: ml,
|
||||||
getMeta: getMeta,
|
|
||||||
// The big channel buffer is a work-around for https://github.com/hashicorp/memberlist/issues/23
|
// The big channel buffer is a work-around for https://github.com/hashicorp/memberlist/issues/23
|
||||||
// More than this many simultaneous events will deadlock cluster.members()
|
// More than this many simultaneous events will deadlock cluster.members()
|
||||||
events: make(chan memberlist.NodeEvent, 100),
|
events: make(chan memberlist.NodeEvent, 100),
|
||||||
|
@ -82,7 +81,12 @@ func (c *Cluster) NotifyConflict(node, other *memberlist.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) NodeMeta(limit int) []byte {
|
func (c *Cluster) NodeMeta(limit int) []byte {
|
||||||
return c.getMeta(limit)
|
encoded, err := c.localNode.Encode(limit)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("failed to encode local node: %s", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return encoded
|
||||||
}
|
}
|
||||||
|
|
||||||
// none of these are used
|
// none of these are used
|
||||||
|
@ -112,7 +116,8 @@ func (c *Cluster) Leave() {
|
||||||
c.ml.Shutdown() //nolint: errcheck
|
c.ml.Shutdown() //nolint: errcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) Update() {
|
func (c *Cluster) Update(localNode common.Node) {
|
||||||
|
c.localNode = localNode
|
||||||
c.ml.UpdateNode(1 * time.Second) // we currently do not update after creation
|
c.ml.UpdateNode(1 * time.Second) // we currently do not update after creation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeMeta holds metadata sent over the cluster
|
// nodeMeta holds metadata sent over the cluster
|
||||||
type NodeMeta struct {
|
type nodeMeta struct {
|
||||||
OverlayAddr net.IPNet
|
OverlayAddr net.IPNet
|
||||||
PubKey string
|
PubKey string
|
||||||
}
|
}
|
||||||
|
@ -20,32 +19,40 @@ type Node struct {
|
||||||
Name string
|
Name string
|
||||||
Addr net.IP
|
Addr net.IP
|
||||||
Meta []byte
|
Meta []byte
|
||||||
NodeMeta
|
nodeMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) String() string {
|
func (n *Node) String() string {
|
||||||
return n.Addr.String()
|
return n.Addr.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncodeNodeMeta(nm NodeMeta, limit int) []byte {
|
func MakeLocalNode(overlayAddr net.IPNet, pubKey string) Node {
|
||||||
buf := &bytes.Buffer{}
|
return Node{
|
||||||
if err := gob.NewEncoder(buf).Encode(nm); err != nil {
|
nodeMeta: nodeMeta{
|
||||||
logrus.Errorf("could not encode local state: %s", err)
|
OverlayAddr: overlayAddr,
|
||||||
return nil
|
PubKey: pubKey,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if buf.Len() > limit {
|
|
||||||
logrus.Errorf("could not fit node metadata into %d bytes", limit)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecodeNodeMeta(b []byte) (NodeMeta, error) {
|
func (n *Node) Encode(limit int) ([]byte, error) {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
if err := gob.NewEncoder(buf).Encode(n.nodeMeta); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not encode local state")
|
||||||
|
}
|
||||||
|
if buf.Len() > limit {
|
||||||
|
return nil, errors.Errorf("could not fit node metadata into %d bytes", limit)
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Decode() error {
|
||||||
// TODO: we blindly trust the info we get from the peers; We should be more defensive to limit the damage a leaked
|
// TODO: we blindly trust the info we get from the peers; We should be more defensive to limit the damage a leaked
|
||||||
// PSK can cause.
|
// PSK can cause.
|
||||||
nm := NodeMeta{}
|
nm := nodeMeta{}
|
||||||
if err := gob.NewDecoder(bytes.NewReader(b)).Decode(&nm); err != nil {
|
if err := gob.NewDecoder(bytes.NewReader(n.Meta)).Decode(&nm); err != nil {
|
||||||
return nm, errors.Wrap(err, "could not decode node meta")
|
return errors.Wrap(err, "could not decode node meta")
|
||||||
}
|
}
|
||||||
return nm, nil
|
n.nodeMeta = nm
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
17
main.go
17
main.go
|
@ -38,19 +38,14 @@ func main() {
|
||||||
logrus.WithError(err).Fatal("could not instantiate wireguard controller")
|
logrus.WithError(err).Fatal("could not instantiate wireguard controller")
|
||||||
}
|
}
|
||||||
|
|
||||||
getMeta := func(limit int) []byte {
|
cluster, err := cluster.New(config.Init, config.ClusterKey, config.BindAddr, config.ClusterPort, config.UseIPAsName)
|
||||||
return common.EncodeNodeMeta(common.NodeMeta{
|
|
||||||
OverlayAddr: wg.OverlayAddr,
|
|
||||||
PubKey: wg.PubKey.String(),
|
|
||||||
}, limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster, err := cluster.New(config.Init, config.ClusterKey, config.BindAddr, config.ClusterPort, config.UseIPAsName, getMeta)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Fatal("could not create cluster")
|
logrus.WithError(err).Fatal("could not create cluster")
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.AssignOverlayAddr((*net.IPNet)(config.OverlayNet), cluster.LocalName)
|
wg.AssignOverlayAddr((*net.IPNet)(config.OverlayNet), cluster.LocalName)
|
||||||
cluster.Update()
|
localNode := common.MakeLocalNode(wg.OverlayAddr, wg.PubKey.String())
|
||||||
|
cluster.Update(localNode)
|
||||||
|
|
||||||
nodec := cluster.Members() // avoid deadlocks by starting before join
|
nodec := cluster.Members() // avoid deadlocks by starting before join
|
||||||
if err := backoff.RetryNotify(
|
if err := backoff.RetryNotify(
|
||||||
|
@ -72,12 +67,10 @@ func main() {
|
||||||
logrus.Info("cluster members:\n")
|
logrus.Info("cluster members:\n")
|
||||||
nodes := make([]common.Node, 0, len(rawNodes))
|
nodes := make([]common.Node, 0, len(rawNodes))
|
||||||
for _, node := range rawNodes {
|
for _, node := range rawNodes {
|
||||||
meta, err := common.DecodeNodeMeta(node.Meta)
|
if err := node.Decode(); err != nil {
|
||||||
if err != nil {
|
|
||||||
logrus.Warnf("\t addr: %s, could not decode metadata", node.Addr)
|
logrus.Warnf("\t addr: %s, could not decode metadata", node.Addr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node.NodeMeta = meta
|
|
||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
logrus.Infof("\taddr: %s, overlay: %s, pubkey: %s", node.Addr, node.OverlayAddr, node.PubKey)
|
logrus.Infof("\taddr: %s, overlay: %s, pubkey: %s", node.Addr, node.OverlayAddr, node.PubKey)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue