mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-11 17:31:12 +01:00
a7d6632298
* Adds management, signal, and relay (STUN/TURN) health probes to the status command. * Adds a reason when the management or signal connections are disconnected. * Adds last wireguard handshake and received/sent bytes per peer
440 lines
12 KiB
Go
440 lines
12 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
"github.com/netbirdio/netbird/client/proto"
|
|
"github.com/netbirdio/netbird/version"
|
|
)
|
|
|
|
func init() {
|
|
loc, err := time.LoadLocation("UTC")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
time.Local = loc
|
|
}
|
|
|
|
var resp = &proto.StatusResponse{
|
|
Status: "Connected",
|
|
FullStatus: &proto.FullStatus{
|
|
Peers: []*proto.PeerState{
|
|
{
|
|
IP: "192.168.178.101",
|
|
PubKey: "Pubkey1",
|
|
Fqdn: "peer-1.awesome-domain.com",
|
|
ConnStatus: "Connected",
|
|
ConnStatusUpdate: timestamppb.New(time.Date(2001, time.Month(1), 1, 1, 1, 1, 0, time.UTC)),
|
|
Relayed: false,
|
|
Direct: true,
|
|
LocalIceCandidateType: "",
|
|
RemoteIceCandidateType: "",
|
|
LocalIceCandidateEndpoint: "",
|
|
RemoteIceCandidateEndpoint: "",
|
|
LastWireguardHandshake: timestamppb.New(time.Date(2001, time.Month(1), 1, 1, 1, 2, 0, time.UTC)),
|
|
BytesRx: 200,
|
|
BytesTx: 100,
|
|
},
|
|
{
|
|
IP: "192.168.178.102",
|
|
PubKey: "Pubkey2",
|
|
Fqdn: "peer-2.awesome-domain.com",
|
|
ConnStatus: "Connected",
|
|
ConnStatusUpdate: timestamppb.New(time.Date(2002, time.Month(2), 2, 2, 2, 2, 0, time.UTC)),
|
|
Relayed: true,
|
|
Direct: false,
|
|
LocalIceCandidateType: "relay",
|
|
RemoteIceCandidateType: "prflx",
|
|
LocalIceCandidateEndpoint: "10.0.0.1:10001",
|
|
RemoteIceCandidateEndpoint: "10.0.10.1:10002",
|
|
LastWireguardHandshake: timestamppb.New(time.Date(2002, time.Month(2), 2, 2, 2, 3, 0, time.UTC)),
|
|
BytesRx: 2000,
|
|
BytesTx: 1000,
|
|
},
|
|
},
|
|
ManagementState: &proto.ManagementState{
|
|
URL: "my-awesome-management.com:443",
|
|
Connected: true,
|
|
Error: "",
|
|
},
|
|
SignalState: &proto.SignalState{
|
|
URL: "my-awesome-signal.com:443",
|
|
Connected: true,
|
|
Error: "",
|
|
},
|
|
Relays: []*proto.RelayState{
|
|
{
|
|
URI: "stun:my-awesome-stun.com:3478",
|
|
Available: true,
|
|
Error: "",
|
|
},
|
|
{
|
|
URI: "turns:my-awesome-turn.com:443?transport=tcp",
|
|
Available: false,
|
|
Error: "context: deadline exceeded",
|
|
},
|
|
},
|
|
LocalPeerState: &proto.LocalPeerState{
|
|
IP: "192.168.178.100/16",
|
|
PubKey: "Some-Pub-Key",
|
|
KernelInterface: true,
|
|
Fqdn: "some-localhost.awesome-domain.com",
|
|
},
|
|
},
|
|
DaemonVersion: "0.14.1",
|
|
}
|
|
|
|
var overview = statusOutputOverview{
|
|
Peers: peersStateOutput{
|
|
Total: 2,
|
|
Connected: 2,
|
|
Details: []peerStateDetailOutput{
|
|
{
|
|
IP: "192.168.178.101",
|
|
PubKey: "Pubkey1",
|
|
FQDN: "peer-1.awesome-domain.com",
|
|
Status: "Connected",
|
|
LastStatusUpdate: time.Date(2001, 1, 1, 1, 1, 1, 0, time.UTC),
|
|
ConnType: "P2P",
|
|
Direct: true,
|
|
IceCandidateType: iceCandidateType{
|
|
Local: "",
|
|
Remote: "",
|
|
},
|
|
IceCandidateEndpoint: iceCandidateType{
|
|
Local: "",
|
|
Remote: "",
|
|
},
|
|
LastWireguardHandshake: time.Date(2001, 1, 1, 1, 1, 2, 0, time.UTC),
|
|
TransferReceived: 200,
|
|
TransferSent: 100,
|
|
},
|
|
{
|
|
IP: "192.168.178.102",
|
|
PubKey: "Pubkey2",
|
|
FQDN: "peer-2.awesome-domain.com",
|
|
Status: "Connected",
|
|
LastStatusUpdate: time.Date(2002, 2, 2, 2, 2, 2, 0, time.UTC),
|
|
ConnType: "Relayed",
|
|
Direct: false,
|
|
IceCandidateType: iceCandidateType{
|
|
Local: "relay",
|
|
Remote: "prflx",
|
|
},
|
|
IceCandidateEndpoint: iceCandidateType{
|
|
Local: "10.0.0.1:10001",
|
|
Remote: "10.0.10.1:10002",
|
|
},
|
|
LastWireguardHandshake: time.Date(2002, 2, 2, 2, 2, 3, 0, time.UTC),
|
|
TransferReceived: 2000,
|
|
TransferSent: 1000,
|
|
},
|
|
},
|
|
},
|
|
CliVersion: version.NetbirdVersion(),
|
|
DaemonVersion: "0.14.1",
|
|
ManagementState: managementStateOutput{
|
|
URL: "my-awesome-management.com:443",
|
|
Connected: true,
|
|
Error: "",
|
|
},
|
|
SignalState: signalStateOutput{
|
|
URL: "my-awesome-signal.com:443",
|
|
Connected: true,
|
|
Error: "",
|
|
},
|
|
Relays: relayStateOutput{
|
|
Total: 2,
|
|
Available: 1,
|
|
Details: []relayStateOutputDetail{
|
|
{
|
|
URI: "stun:my-awesome-stun.com:3478",
|
|
Available: true,
|
|
Error: "",
|
|
},
|
|
{
|
|
URI: "turns:my-awesome-turn.com:443?transport=tcp",
|
|
Available: false,
|
|
Error: "context: deadline exceeded",
|
|
},
|
|
},
|
|
},
|
|
IP: "192.168.178.100/16",
|
|
PubKey: "Some-Pub-Key",
|
|
KernelInterface: true,
|
|
FQDN: "some-localhost.awesome-domain.com",
|
|
}
|
|
|
|
func TestConversionFromFullStatusToOutputOverview(t *testing.T) {
|
|
convertedResult := convertToStatusOutputOverview(resp)
|
|
|
|
assert.Equal(t, overview, convertedResult)
|
|
}
|
|
|
|
func TestSortingOfPeers(t *testing.T) {
|
|
peers := []peerStateDetailOutput{
|
|
{
|
|
IP: "192.168.178.104",
|
|
},
|
|
{
|
|
IP: "192.168.178.102",
|
|
},
|
|
{
|
|
IP: "192.168.178.101",
|
|
},
|
|
{
|
|
IP: "192.168.178.105",
|
|
},
|
|
{
|
|
IP: "192.168.178.103",
|
|
},
|
|
}
|
|
|
|
sortPeersByIP(peers)
|
|
|
|
assert.Equal(t, peers[3].IP, "192.168.178.104")
|
|
}
|
|
|
|
func TestParsingToJSON(t *testing.T) {
|
|
jsonString, _ := parseToJSON(overview)
|
|
|
|
//@formatter:off
|
|
expectedJSONString := `
|
|
{
|
|
"peers": {
|
|
"total": 2,
|
|
"connected": 2,
|
|
"details": [
|
|
{
|
|
"fqdn": "peer-1.awesome-domain.com",
|
|
"netbirdIp": "192.168.178.101",
|
|
"publicKey": "Pubkey1",
|
|
"status": "Connected",
|
|
"lastStatusUpdate": "2001-01-01T01:01:01Z",
|
|
"connectionType": "P2P",
|
|
"direct": true,
|
|
"iceCandidateType": {
|
|
"local": "",
|
|
"remote": ""
|
|
},
|
|
"iceCandidateEndpoint": {
|
|
"local": "",
|
|
"remote": ""
|
|
},
|
|
"lastWireguardHandshake": "2001-01-01T01:01:02Z",
|
|
"transferReceived": 200,
|
|
"transferSent": 100
|
|
},
|
|
{
|
|
"fqdn": "peer-2.awesome-domain.com",
|
|
"netbirdIp": "192.168.178.102",
|
|
"publicKey": "Pubkey2",
|
|
"status": "Connected",
|
|
"lastStatusUpdate": "2002-02-02T02:02:02Z",
|
|
"connectionType": "Relayed",
|
|
"direct": false,
|
|
"iceCandidateType": {
|
|
"local": "relay",
|
|
"remote": "prflx"
|
|
},
|
|
"iceCandidateEndpoint": {
|
|
"local": "10.0.0.1:10001",
|
|
"remote": "10.0.10.1:10002"
|
|
},
|
|
"lastWireguardHandshake": "2002-02-02T02:02:03Z",
|
|
"transferReceived": 2000,
|
|
"transferSent": 1000
|
|
}
|
|
]
|
|
},
|
|
"cliVersion": "development",
|
|
"daemonVersion": "0.14.1",
|
|
"management": {
|
|
"url": "my-awesome-management.com:443",
|
|
"connected": true,
|
|
"error": ""
|
|
},
|
|
"signal": {
|
|
"url": "my-awesome-signal.com:443",
|
|
"connected": true,
|
|
"error": ""
|
|
},
|
|
"relays": {
|
|
"total": 2,
|
|
"available": 1,
|
|
"details": [
|
|
{
|
|
"uri": "stun:my-awesome-stun.com:3478",
|
|
"available": true,
|
|
"error": ""
|
|
},
|
|
{
|
|
"uri": "turns:my-awesome-turn.com:443?transport=tcp",
|
|
"available": false,
|
|
"error": "context: deadline exceeded"
|
|
}
|
|
]
|
|
},
|
|
"netbirdIp": "192.168.178.100/16",
|
|
"publicKey": "Some-Pub-Key",
|
|
"usesKernelInterface": true,
|
|
"fqdn": "some-localhost.awesome-domain.com"
|
|
}`
|
|
// @formatter:on
|
|
|
|
var expectedJSON bytes.Buffer
|
|
require.NoError(t, json.Compact(&expectedJSON, []byte(expectedJSONString)))
|
|
|
|
assert.Equal(t, expectedJSON.String(), jsonString)
|
|
}
|
|
|
|
func TestParsingToYAML(t *testing.T) {
|
|
yaml, _ := parseToYAML(overview)
|
|
|
|
expectedYAML :=
|
|
`peers:
|
|
total: 2
|
|
connected: 2
|
|
details:
|
|
- fqdn: peer-1.awesome-domain.com
|
|
netbirdIp: 192.168.178.101
|
|
publicKey: Pubkey1
|
|
status: Connected
|
|
lastStatusUpdate: 2001-01-01T01:01:01Z
|
|
connectionType: P2P
|
|
direct: true
|
|
iceCandidateType:
|
|
local: ""
|
|
remote: ""
|
|
iceCandidateEndpoint:
|
|
local: ""
|
|
remote: ""
|
|
lastWireguardHandshake: 2001-01-01T01:01:02Z
|
|
transferReceived: 200
|
|
transferSent: 100
|
|
- fqdn: peer-2.awesome-domain.com
|
|
netbirdIp: 192.168.178.102
|
|
publicKey: Pubkey2
|
|
status: Connected
|
|
lastStatusUpdate: 2002-02-02T02:02:02Z
|
|
connectionType: Relayed
|
|
direct: false
|
|
iceCandidateType:
|
|
local: relay
|
|
remote: prflx
|
|
iceCandidateEndpoint:
|
|
local: 10.0.0.1:10001
|
|
remote: 10.0.10.1:10002
|
|
lastWireguardHandshake: 2002-02-02T02:02:03Z
|
|
transferReceived: 2000
|
|
transferSent: 1000
|
|
cliVersion: development
|
|
daemonVersion: 0.14.1
|
|
management:
|
|
url: my-awesome-management.com:443
|
|
connected: true
|
|
error: ""
|
|
signal:
|
|
url: my-awesome-signal.com:443
|
|
connected: true
|
|
error: ""
|
|
relays:
|
|
total: 2
|
|
available: 1
|
|
details:
|
|
- uri: stun:my-awesome-stun.com:3478
|
|
available: true
|
|
error: ""
|
|
- uri: turns:my-awesome-turn.com:443?transport=tcp
|
|
available: false
|
|
error: 'context: deadline exceeded'
|
|
netbirdIp: 192.168.178.100/16
|
|
publicKey: Some-Pub-Key
|
|
usesKernelInterface: true
|
|
fqdn: some-localhost.awesome-domain.com
|
|
`
|
|
|
|
assert.Equal(t, expectedYAML, yaml)
|
|
}
|
|
|
|
func TestParsingToDetail(t *testing.T) {
|
|
detail := parseToFullDetailSummary(overview)
|
|
|
|
expectedDetail :=
|
|
`Peers detail:
|
|
peer-1.awesome-domain.com:
|
|
NetBird IP: 192.168.178.101
|
|
Public key: Pubkey1
|
|
Status: Connected
|
|
-- detail --
|
|
Connection type: P2P
|
|
Direct: true
|
|
ICE candidate (Local/Remote): -/-
|
|
ICE candidate endpoints (Local/Remote): -/-
|
|
Last connection update: 2001-01-01 01:01:01
|
|
Last Wireguard handshake: 2001-01-01 01:01:02
|
|
Transfer status (received/sent) 200 B/100 B
|
|
|
|
peer-2.awesome-domain.com:
|
|
NetBird IP: 192.168.178.102
|
|
Public key: Pubkey2
|
|
Status: Connected
|
|
-- detail --
|
|
Connection type: Relayed
|
|
Direct: false
|
|
ICE candidate (Local/Remote): relay/prflx
|
|
ICE candidate endpoints (Local/Remote): 10.0.0.1:10001/10.0.10.1:10002
|
|
Last connection update: 2002-02-02 02:02:02
|
|
Last Wireguard handshake: 2002-02-02 02:02:03
|
|
Transfer status (received/sent) 2.0 KiB/1000 B
|
|
|
|
Daemon version: 0.14.1
|
|
CLI version: development
|
|
Management: Connected to my-awesome-management.com:443
|
|
Signal: Connected to my-awesome-signal.com:443
|
|
Relays:
|
|
[stun:my-awesome-stun.com:3478] is Available
|
|
[turns:my-awesome-turn.com:443?transport=tcp] is Unavailable, reason: context: deadline exceeded
|
|
FQDN: some-localhost.awesome-domain.com
|
|
NetBird IP: 192.168.178.100/16
|
|
Interface type: Kernel
|
|
Peers count: 2/2 Connected
|
|
`
|
|
|
|
assert.Equal(t, expectedDetail, detail)
|
|
}
|
|
|
|
func TestParsingToShortVersion(t *testing.T) {
|
|
shortVersion := parseGeneralSummary(overview, false, false)
|
|
|
|
expectedString :=
|
|
`Daemon version: 0.14.1
|
|
CLI version: development
|
|
Management: Connected
|
|
Signal: Connected
|
|
Relays: 1/2 Available
|
|
FQDN: some-localhost.awesome-domain.com
|
|
NetBird IP: 192.168.178.100/16
|
|
Interface type: Kernel
|
|
Peers count: 2/2 Connected
|
|
`
|
|
|
|
assert.Equal(t, expectedString, shortVersion)
|
|
}
|
|
|
|
func TestParsingOfIP(t *testing.T) {
|
|
InterfaceIP := "192.168.178.123/16"
|
|
|
|
parsedIP := parseInterfaceIP(InterfaceIP)
|
|
|
|
assert.Equal(t, "192.168.178.123\n", parsedIP)
|
|
}
|