Skip to content

Commit 58accde

Browse files
authored
Merge pull request #31 from devilcove/update/peerDetails
private endpoints
2 parents 55bb4d9 + 3220a4a commit 58accde

File tree

19 files changed

+352
-106
lines changed

19 files changed

+352
-106
lines changed

app/plexus-agent/cmd/set.go

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,35 @@ var setCmd = &cobra.Command{
3030
Use: "set ip [network]",
3131
Args: cobra.RangeArgs(1, 2),
3232
Short: "set private endpoint for network",
33-
Long: `set private endpoint ip for a or all networks.`,
33+
Long: `set/reset private endpoint ip for a or all networks.
34+
To reset set "" [network]`,
3435
Run: func(cmd *cobra.Command, args []string) {
3536
network := ""
3637
if len(args) > 1 {
3738
network = args[1]
3839
}
3940
fmt.Println("set called")
40-
ip := net.ParseIP(args[0])
41-
if ip == nil {
42-
fmt.Println("invalid ip")
43-
return
44-
}
45-
addr, err := netlink.AddrList(nil, netlink.FAMILY_V4)
46-
if err != nil {
47-
fmt.Println("error getting addresses", err)
48-
return
49-
}
50-
found := false
51-
for _, add := range addr {
52-
if ip.Equal(add.IP) {
53-
found = true
41+
if args[0] != "" {
42+
ip := net.ParseIP(args[0])
43+
if ip == nil {
44+
fmt.Println("invalid ip")
45+
return
46+
}
47+
addr, err := netlink.AddrList(nil, netlink.FAMILY_V4)
48+
if err != nil {
49+
fmt.Println("error getting addresses", err)
50+
return
51+
}
52+
found := false
53+
for _, add := range addr {
54+
if ip.Equal(add.IP) {
55+
found = true
56+
}
57+
}
58+
if !found {
59+
fmt.Println("invalid ip")
60+
return
5461
}
55-
}
56-
if !found {
57-
fmt.Println("invalid ip")
58-
return
5962
}
6063
request := plexus.PrivateEndpoint{
6164
IP: args[0],

app/plexus-agent/cmd/status.go

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ package cmd
1818
import (
1919
"fmt"
2020
"log/slog"
21+
"math"
2122
"slices"
2223
"strconv"
2324
"time"
2425

2526
"github.com/devilcove/plexus"
2627
"github.com/devilcove/plexus/internal/agent"
28+
"github.com/fatih/color"
2729
"github.com/kr/pretty"
2830
"github.com/spf13/cobra"
2931
"github.com/vishvananda/netlink"
@@ -47,8 +49,16 @@ var statusCmd = &cobra.Command{
4749
fmt.Println("agent running... not connected to servers")
4850
return
4951
}
50-
fmt.Println("Server")
51-
fmt.Println("\t", status.Server, ":", status.Connected)
52+
color.Green("Server")
53+
var colour func(a ...interface{}) string
54+
if status.Connected {
55+
colour = color.New(color.FgGreen).SprintFunc()
56+
} else {
57+
colour = color.New(color.FgRed).SprintFunc()
58+
59+
}
60+
fmt.Println("\t", status.Server, ":", colour(status.Connected))
61+
5262
if len(status.Networks) == 0 {
5363
fmt.Println("no networks")
5464
return
@@ -68,7 +78,7 @@ var statusCmd = &cobra.Command{
6878
if err != nil {
6979
slog.Error("get address of interface", "interface", network.Interface, "error", err)
7080
}
71-
fmt.Println("interface:", network.Interface)
81+
color.Magenta("interface %s", network.Interface)
7282
fmt.Println("\t network name:", network.Name)
7383
fmt.Println("\t public key:", wg.PrivateKey.PublicKey())
7484
fmt.Println("\t listen port:", wg.ListenPort)
@@ -91,24 +101,22 @@ var statusCmd = &cobra.Command{
91101
break
92102
}
93103
}
94-
fmt.Println("peer:", peer.WGPublicKey, peer.HostName, peer.Address.IP)
104+
color.Yellow("peer: %s %s %s", peer.WGPublicKey, peer.HostName, peer.Address.IP)
95105
if peer.IsRelay {
96106
fmt.Println("\trelay: true")
97107
showRelayedPeers(peer.RelayedPeers, network)
98108
}
99-
fmt.Println("\tendpoint:", peer.Endpoint.String()+":", peer.PublicListenPort)
109+
fmt.Println("\tprivate-endpoint:", peer.PrivateEndpoint.String()+":", peer.ListenPort)
110+
fmt.Println("\tpublic-endpoint:", peer.Endpoint.String()+":", peer.PublicListenPort)
111+
fmt.Println("\twg-endpoint:", wgPeer.Endpoint)
100112
fmt.Print("\tallowed ips:")
101113
for _, ip := range wgPeer.AllowedIPs {
102114
ones, _ := ip.Mask.Size()
103115
fmt.Print(" " + ip.IP.String() + "/" + strconv.Itoa(ones))
104116
}
105117
fmt.Println()
106-
if wgPeer.LastHandshakeTime.IsZero() {
107-
fmt.Println("\tlast handshake: never")
108-
} else {
109-
fmt.Printf("\tlast handshake: %f0.0 %s\n", time.Since(wgPeer.LastHandshakeTime).Seconds(), "seconds ago")
110-
}
111-
fmt.Println("\ttransfer:", wgPeer.TransmitBytes, "sent", wgPeer.ReceiveBytes, "received")
118+
printHandshake(wgPeer.LastHandshakeTime)
119+
fmt.Println("\ttransfer:", prettyByteSize(wgPeer.TransmitBytes), "sent", prettyByteSize(wgPeer.ReceiveBytes), "received")
112120
fmt.Println("\tkeepalive:", wgPeer.PersistentKeepaliveInterval)
113121
}
114122
fmt.Println()
@@ -140,3 +148,52 @@ func showRelayedPeers(relayed []string, network agent.Network) {
140148
}
141149
}
142150
}
151+
152+
func printHandshake(handshake time.Time) {
153+
if handshake.IsZero() {
154+
fmt.Printf("\tlast handshake: %s\n", color.RedString("never"))
155+
return
156+
}
157+
d := time.Since(handshake)
158+
hour := int(d.Hours())
159+
minute := int(d.Minutes()) % 60
160+
second := int(d.Seconds()) % 60
161+
var hourString, minuteString, secondString string
162+
if hour == 0 {
163+
hourString = ""
164+
} else if hour == 1 {
165+
hourString = fmt.Sprintf("1 %s", color.GreenString("hour"))
166+
} else {
167+
hourString = fmt.Sprintf("%d %s", hour, color.GreenString("hours"))
168+
}
169+
if minute == 0 && hour == 0 {
170+
minuteString = ""
171+
} else if minute == 1 {
172+
minuteString = fmt.Sprintf("1 %s", color.GreenString("minute"))
173+
} else {
174+
minuteString = fmt.Sprintf("%d %s", minute, color.GreenString("minutes"))
175+
}
176+
if minute == 0 && hour == 0 && second == 0 {
177+
secondString = color.RedString("never")
178+
} else if second == 1 {
179+
secondString = fmt.Sprintf("1 %s", color.GreenString("second"))
180+
} else {
181+
secondString = fmt.Sprintf("%d %s", second, color.GreenString("seconds"))
182+
}
183+
fmt.Println("\tlast handshake:", hourString, minuteString, secondString, "ago")
184+
}
185+
186+
func prettyByteSize(b int64) string {
187+
bf := float64(b)
188+
for i, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei"} {
189+
if math.Abs(bf) < 1024.0 {
190+
units := color.GreenString("%sB", unit)
191+
if i == 0 {
192+
return fmt.Sprintf("%1.0f %s", bf, units)
193+
}
194+
return fmt.Sprintf("%3.2f %s", bf, units)
195+
}
196+
bf /= 1024.0
197+
}
198+
return ""
199+
}

app/plexus-agent/cmd/status_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package cmd
2+
3+
import (
4+
"os"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestPrintHandshake(t *testing.T) {
12+
bytes := make([]byte, 128)
13+
out, err := os.Open(os.Stdout.Name())
14+
assert.Nil(t, err)
15+
t.Run("one second", func(t *testing.T) {
16+
printHandshake(time.Now().Add(time.Second * -1))
17+
_, err := out.Read(bytes)
18+
assert.Nil(t, err)
19+
assert.Contains(t, string(bytes), "1 second ago")
20+
assert.Nil(t, out.Close())
21+
})
22+
t.Run("one minute", func(t *testing.T) {
23+
out, err := os.Open(os.Stdout.Name())
24+
assert.Nil(t, err)
25+
printHandshake(time.Now().Add(time.Second * -60))
26+
_, err = out.Read(bytes)
27+
assert.Nil(t, err)
28+
assert.Contains(t, string(bytes), "1 minute 0 seconds ago")
29+
assert.Nil(t, out.Close())
30+
})
31+
t.Run("hours", func(t *testing.T) {
32+
out, err := os.Open(os.Stdout.Name())
33+
assert.Nil(t, err)
34+
printHandshake(time.Now().Add(time.Second * -3600))
35+
_, err = out.Read(bytes)
36+
assert.Nil(t, err)
37+
assert.Contains(t, string(bytes), "1 hour 0 minutes 0 seconds ago")
38+
assert.Nil(t, out.Close())
39+
})
40+
t.Run("multi", func(t *testing.T) {
41+
out, err := os.Open(os.Stdout.Name())
42+
assert.Nil(t, err)
43+
printHandshake(time.Now().Add(time.Second * -7250))
44+
_, err = out.Read(bytes)
45+
assert.Nil(t, err)
46+
assert.Contains(t, string(bytes), "2 hours 0 minutes 50 seconds ago")
47+
assert.Nil(t, out.Close())
48+
})
49+
t.Run("now", func(t *testing.T) {
50+
out, err := os.Open(os.Stdout.Name())
51+
assert.Nil(t, err)
52+
printHandshake(time.Now())
53+
_, err = out.Read(bytes)
54+
assert.Nil(t, err)
55+
assert.Contains(t, string(bytes), "never")
56+
assert.Nil(t, out.Close())
57+
})
58+
}
59+
60+
func TestPrettyByteSize(t *testing.T) {
61+
assert.Equal(t, "0 B", prettyByteSize(0))
62+
assert.Equal(t, "86 B", prettyByteSize(86))
63+
assert.Equal(t, "120 B", prettyByteSize(120))
64+
assert.Equal(t, "1.03 KiB", prettyByteSize(1050))
65+
assert.Equal(t, "8.00 EiB", prettyByteSize(9223372036854775807))
66+
}

app/plexus-agent/cmd/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"github.com/spf13/cobra"
2626
)
2727

28-
const version = "v0.1.0"
28+
const version = "v0.2.1"
2929

3030
// versionCmd represents the version command
3131
var versionCmd = &cobra.Command{

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/c-robinson/iplib v1.0.8
77
github.com/caddyserver/certmagic v0.20.0
88
github.com/devilcove/boltdb v0.1.5
9+
github.com/fatih/color v1.16.0
910
github.com/gin-contrib/sessions v1.0.0
1011
github.com/gin-gonic/gin v1.9.1
1112
github.com/google/nftables v0.2.0
@@ -50,6 +51,7 @@ require (
5051
github.com/leodido/go-urn v1.4.0 // indirect
5152
github.com/libdns/libdns v0.2.1 // indirect
5253
github.com/magiconair/properties v1.8.7 // indirect
54+
github.com/mattn/go-colorable v0.1.13 // indirect
5355
github.com/mattn/go-isatty v0.0.20 // indirect
5456
github.com/mdlayher/genetlink v1.3.2 // indirect
5557
github.com/mdlayher/netlink v1.7.2 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
2323
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2424
github.com/devilcove/boltdb v0.1.5 h1:yqxKoJUgUthzMD6aD2jDLc4M02yD4SRhbS3kARhVUtg=
2525
github.com/devilcove/boltdb v0.1.5/go.mod h1:eyp3/ugxxIAlFC5jRBOyCKgE3CGj5xhYoVhpWqyWy80=
26+
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
27+
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
2628
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
2729
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
2830
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
@@ -88,6 +90,9 @@ github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
8890
github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
8991
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
9092
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
93+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
94+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
95+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
9196
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
9297
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
9398
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
@@ -229,6 +234,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
229234
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
230235
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
231236
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
237+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
232238
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
233239
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
234240
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

internal/agent/broker.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net"
99
"runtime/debug"
1010
"strings"
11+
"time"
1112

1213
"github.com/devilcove/boltdb"
1314
"github.com/devilcove/plexus"
@@ -217,6 +218,7 @@ func subcribe(ec *nats.EncodedConn) {
217218
for i, peer := range network.Peers {
218219
if peer.WGPublicKey == self.WGPublicKey {
219220
network.Peers[i].PrivateEndpoint = net.ParseIP(request.IP)
221+
network.Peers[i].UsePrivateEndpoint = false
220222
if err := publishNetworkPeerUpdate(self, &network.Peers[i]); err != nil {
221223
_ = ec.Publish(reply, plexus.MessageResponse{
222224
Message: "error publishing update to server " + err.Error(),
@@ -230,6 +232,9 @@ func subcribe(ec *nats.EncodedConn) {
230232
})
231233
}
232234
}
235+
restartEndpointServer <- struct{}{}
236+
//wait to ensure endpoint server is started
237+
time.Sleep(time.Millisecond * 10)
233238
_ = ec.Publish(reply, plexus.MessageResponse{
234239
Message: "private endpoint added",
235240
})

internal/agent/config.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@ import (
99
)
1010

1111
const (
12-
defaultWGPort = 51820
13-
maxNetworks = 100
14-
defaultKeepalive = time.Second * 20
15-
NatsTimeout = time.Second * 5
16-
NatsLongTimeout = time.Second * 15
17-
checkinTime = time.Minute * 1
18-
serverCheckTime = time.Hour * 1
19-
connectivityTimeout = time.Minute * 3
20-
networkNotMapped = "network not mapped to server"
21-
version = "v0.2.1"
22-
networkTable = "networks"
23-
deviceTable = "devices"
24-
path = "/var/lib/plexus/"
12+
defaultWGPort = 51820
13+
maxNetworks = 100
14+
defaultKeepalive = time.Second * 20
15+
NatsTimeout = time.Second * 5
16+
NatsLongTimeout = time.Second * 15
17+
checkinTime = time.Minute * 1
18+
serverCheckTime = time.Minute * 3
19+
connectivityTimeout = time.Minute * 3
20+
endpointServerTimeout = time.Second * 30
21+
networkNotMapped = "network not mapped to server"
22+
version = "v0.2.1"
23+
networkTable = "networks"
24+
deviceTable = "devices"
25+
path = "/var/lib/plexus/"
2526
)
2627

2728
var (

0 commit comments

Comments
 (0)