cluster: decouple RingID from WireguardInterfaceID
Signed-off-by: Alejandro Mery <amery@jpi.io>
This commit is contained in:
+80
-12
@@ -4,28 +4,86 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
|
||||
"git.jpi.io/amery/jpictl/pkg/rings"
|
||||
"git.jpi.io/amery/jpictl/pkg/wireguard"
|
||||
)
|
||||
|
||||
const (
|
||||
// RingsCount indicates how many wireguard rings we have
|
||||
RingsCount = 2
|
||||
// RingZeroPort is the port wireguard uses for ring0
|
||||
RingZeroPort = 51800
|
||||
// RingOnePort is the port wireguard uses for ring1
|
||||
RingOnePort = 51810
|
||||
)
|
||||
|
||||
// WireguardInterfaceID represents the number in the `wg%v`
|
||||
// interface name.
|
||||
type WireguardInterfaceID uint
|
||||
|
||||
// AsWireguardInterfaceID returns the [WireguardInterfaceID] for
|
||||
// a valid [rings.RingID].
|
||||
func AsWireguardInterfaceID(ring rings.RingID) (WireguardInterfaceID, error) {
|
||||
switch ring {
|
||||
case rings.RingZeroID:
|
||||
return 0, nil
|
||||
case rings.RingOneID:
|
||||
return 1, nil
|
||||
default:
|
||||
return 0, ErrInvalidRing(ring)
|
||||
}
|
||||
}
|
||||
|
||||
// MustWireguardInterfaceID returns the [WireguardInterfaceID] for
|
||||
// a valid [rings.RingID], and panics if it's not.
|
||||
func MustWireguardInterfaceID(ring rings.RingID) WireguardInterfaceID {
|
||||
id, err := AsWireguardInterfaceID(ring)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// RingID tells the [rings.RingID] of the [WireguardInterfaceID].
|
||||
func (wi WireguardInterfaceID) RingID() rings.RingID {
|
||||
return rings.RingID(wi + 1)
|
||||
}
|
||||
|
||||
// PubFile returns "wgN.pub"
|
||||
func (wi WireguardInterfaceID) PubFile() string {
|
||||
return fmt.Sprintf("wg%v.pub", wi)
|
||||
}
|
||||
|
||||
// KeyFile returns "wgN.key"
|
||||
func (wi WireguardInterfaceID) KeyFile() string {
|
||||
return fmt.Sprintf("wg%v.key", wi)
|
||||
}
|
||||
|
||||
// ConfFile returns "wgN.conf"
|
||||
func (wi WireguardInterfaceID) ConfFile() string {
|
||||
return fmt.Sprintf("wg%v.conf", wi)
|
||||
}
|
||||
|
||||
// Files returns all wgN.ext file names.
|
||||
func (wi WireguardInterfaceID) Files() (keyFile, pubFile, confFile string) {
|
||||
prefix := "wg" + strconv.Itoa(int(wi))
|
||||
|
||||
return prefix + ".key", prefix + ".pub", prefix + ".conf"
|
||||
}
|
||||
|
||||
// RingInfo contains represents the Wireguard endpoint details
|
||||
// for a Machine on a particular ring
|
||||
type RingInfo struct {
|
||||
Ring int
|
||||
Ring WireguardInterfaceID
|
||||
Enabled bool
|
||||
Keys wireguard.KeyPair
|
||||
}
|
||||
|
||||
// RingID returns the [rings.RingID] for this [RingInfo].
|
||||
func (ri *RingInfo) RingID() rings.RingID {
|
||||
return rings.RingID(ri.Ring + 1)
|
||||
}
|
||||
|
||||
// Merge attempts to combine two RingInfo structs
|
||||
func (ri *RingInfo) Merge(alter *RingInfo) error {
|
||||
switch {
|
||||
@@ -51,7 +109,7 @@ func (ri *RingInfo) unsafeMerge(alter *RingInfo) error {
|
||||
ri.Enabled = true
|
||||
}
|
||||
|
||||
// fill the gaps on our keypair
|
||||
// fill the gaps on our key pair
|
||||
if ri.Keys.PrivateKey.IsZero() {
|
||||
ri.Keys.PrivateKey = alter.Keys.PrivateKey
|
||||
}
|
||||
@@ -76,7 +134,7 @@ func canMergeKeyPairs(p1, p2 wireguard.KeyPair) bool {
|
||||
// RingAddressEncoder provides encoder/decoder access for a particular
|
||||
// Wireguard ring
|
||||
type RingAddressEncoder struct {
|
||||
ID int
|
||||
ID rings.RingID
|
||||
Port uint16
|
||||
Encode func(zoneID rings.ZoneID, nodeID rings.NodeID) (netip.Addr, bool)
|
||||
Decode func(addr netip.Addr) (zoneID rings.ZoneID, nodeID rings.NodeID, ok bool)
|
||||
@@ -85,20 +143,20 @@ type RingAddressEncoder struct {
|
||||
var (
|
||||
// RingZero is a wg0 address encoder/decoder
|
||||
RingZero = RingAddressEncoder{
|
||||
ID: 0,
|
||||
ID: rings.RingZeroID,
|
||||
Port: RingZeroPort,
|
||||
Decode: ParseRingZeroAddress,
|
||||
Encode: RingZeroAddress,
|
||||
}
|
||||
// RingOne is a wg1 address encoder/decoder
|
||||
RingOne = RingAddressEncoder{
|
||||
ID: 1,
|
||||
ID: rings.RingOneID,
|
||||
Port: RingOnePort,
|
||||
Decode: ParseRingOneAddress,
|
||||
Encode: RingOneAddress,
|
||||
}
|
||||
// Rings provides indexed access to the ring address encoders
|
||||
Rings = [RingsCount]RingAddressEncoder{
|
||||
Rings = []RingAddressEncoder{
|
||||
RingZero,
|
||||
RingOne,
|
||||
}
|
||||
@@ -323,10 +381,20 @@ func (rp *RingPeer) AllowCIDR(addr netip.Addr, bits int) {
|
||||
}
|
||||
|
||||
// NewRing composes a new Ring for Wireguard setup
|
||||
func NewRing(z ZoneIterator, m MachineIterator, ring int) (*Ring, error) {
|
||||
r := &Ring{
|
||||
RingAddressEncoder: Rings[ring],
|
||||
ZoneIterator: z,
|
||||
func NewRing(z ZoneIterator, m MachineIterator, ringID rings.RingID) (*Ring, error) {
|
||||
var r *Ring
|
||||
for _, ring := range Rings {
|
||||
if ringID == ring.ID {
|
||||
r = &Ring{
|
||||
RingAddressEncoder: ring,
|
||||
ZoneIterator: z,
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
return nil, ErrInvalidRing(ringID)
|
||||
}
|
||||
|
||||
m.ForEachMachine(func(p *Machine) bool {
|
||||
|
||||
Reference in New Issue
Block a user