diff --git a/pkg/zones/errors.go b/pkg/zones/errors.go new file mode 100644 index 0000000..6fd068f --- /dev/null +++ b/pkg/zones/errors.go @@ -0,0 +1,16 @@ +package zones + +import "errors" + +var ( + // ErrInvalidName indicates the name isn't valid + ErrInvalidName = errors.New("invalid name") + + // ErrUnknownNode indicates there is a reference to a node + // we don't have on the tree + ErrUnknownNode = errors.New("node does not exist") + + // ErrInvalidNode indicates the nodes can't be used for + // the intended purpose + ErrInvalidNode = errors.New("invalid node") +) diff --git a/pkg/zones/machine_rings.go b/pkg/zones/machine_rings.go index 9e774e4..af811e3 100644 --- a/pkg/zones/machine_rings.go +++ b/pkg/zones/machine_rings.go @@ -2,6 +2,7 @@ package zones import ( "bytes" + "errors" "fmt" "os" @@ -135,7 +136,11 @@ func (m *Machine) applyWireguardConfig(ring int, wg *wireguard.Config) error { } for _, peer := range wg.Peer { - if err := m.applyWireguardPeerConfig(ring, peer); err != nil { + err := m.applyWireguardPeerConfig(ring, peer) + switch { + case errors.Is(err, ErrUnknownNode): + // ignore unknown peers + case err != nil: err = core.Wrapf(err, "%s: wg%v:%s", m.Name, ring, addr) return err } @@ -183,8 +188,10 @@ func (m *Machine) applyWireguardPeerConfig(ring int, pc wireguard.PeerConfig) er switch { case !found: // unknown + return core.Wrap(ErrUnknownNode, pc.Endpoint.Host) case ring == 1 && m.zone != peer.zone: // invalid zone + return core.Wrap(ErrInvalidNode, peer.Name) default: // apply RingInfo ri := &RingInfo{ @@ -197,8 +204,6 @@ func (m *Machine) applyWireguardPeerConfig(ring int, pc wireguard.PeerConfig) er return peer.applyRingInfo(ring, ri) } - - return fmt.Errorf("%q: invalid peer endpoint", pc.Endpoint.Host) } func (m *Machine) applyZoneNodeID(zoneID, nodeID int) error { diff --git a/pkg/zones/machine_scan.go b/pkg/zones/machine_scan.go index 52efe6e..aca379e 100644 --- a/pkg/zones/machine_scan.go +++ b/pkg/zones/machine_scan.go @@ -4,7 +4,10 @@ import ( "context" "net/netip" "strconv" + "strings" "time" + + "darvaza.org/core" ) // LookupNetIP uses the DNS Resolver to get the public addresses associated @@ -30,21 +33,32 @@ func (m *Machine) UpdatePublicAddresses() error { func (m *Machine) init() error { if err := m.setID(); err != nil { - return err + return core.Wrap(err, m.Name) } for i := 0; i < RingsCount; i++ { if err := m.tryReadWireguardKeys(i); err != nil { - return err + return core.Wrap(err, m.Name) } } + return nil } func (m *Machine) setID() error { zoneName := m.zone.Name - suffix := m.Name[len(zoneName)+1:] + l := len(zoneName) + switch { + case len(m.Name) < l+2: + return ErrInvalidName + case !strings.HasPrefix(m.Name, zoneName): + return ErrInvalidName + case m.Name[l] != '-': + return ErrInvalidName + } + + suffix := m.Name[l+1:] id, err := strconv.ParseInt(suffix, 10, 8) if err != nil { return err diff --git a/pkg/zones/scan.go b/pkg/zones/scan.go index bb07afc..20a73ff 100644 --- a/pkg/zones/scan.go +++ b/pkg/zones/scan.go @@ -3,6 +3,8 @@ package zones import ( "io/fs" "sort" + + "darvaza.org/core" ) func (m *Zones) scan(opts *ScanOptions) error { @@ -31,23 +33,32 @@ func (m *Zones) scanDirectory(_ *ScanOptions) error { for _, e := range entries { if e.IsDir() { - z := &Zone{ - zones: m, - logger: m, - Name: e.Name(), - } - - if err := z.scan(); err != nil { - return err + z, err := m.newZone(e.Name()) + switch { + case err != nil: + return core.Wrap(err, e.Name()) + case z.Machines.Len() > 0: + m.Zones = append(m.Zones, z) } - - m.Zones = append(m.Zones, z) } } return nil } +func (m *Zones) newZone(name string) (*Zone, error) { + z := &Zone{ + zones: m, + logger: m, + Name: name, + } + + if err := z.scan(); err != nil { + return nil, err + } + return z, nil +} + func (m *Zones) scanMachines(opts *ScanOptions) error { var err error m.ForEachMachine(func(p *Machine) bool {