Added Output struct to properly name json and yaml attr's and add missing tests

This commit is contained in:
Pascal Fischer 2023-02-24 19:01:54 +01:00
parent e75535d30b
commit 78c6231c01
2 changed files with 464 additions and 234 deletions

View File

@ -4,22 +4,64 @@ import (
"context"
"encoding/json"
"fmt"
yaml2 "gopkg.in/yaml.v2"
"net"
"net/netip"
"sort"
"strings"
"time"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
"gopkg.in/yaml.v2"
"github.com/netbirdio/netbird/client/internal"
"github.com/netbirdio/netbird/client/internal/peer"
"github.com/netbirdio/netbird/client/proto"
nbStatus "github.com/netbirdio/netbird/client/status"
"github.com/netbirdio/netbird/client/system"
"github.com/netbirdio/netbird/util"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
)
type peerStateDetailOutput struct {
IP string `json:"ip" yaml:"ip"`
PubKey string `json:"publicKey" yaml:"publicKey"`
FQDN string `json:"fqdn" yaml:"fqdn"`
ConnStatus string `json:"connectionStatus" yaml:"connectionStatus"`
ConnStatusUpdate time.Time `json:"connectionStatusUpdate" yaml:"connectionStatusUpdate"`
ConnType string `json:"connectionType" yaml:"connectionType"`
Direct bool `json:"direct" yaml:"direct"`
LocalIceCandidateType string `json:"localIceCandidateType" yaml:"localIceCandidateType"`
RemoteIceCandidateType string `json:"remoteIceCandidateType" yaml:"remoteIceCandidateType"`
}
type peersStateOutput struct {
Total int `json:"total" yaml:"total"`
Connected int `json:"connected" yaml:"connected"`
Details []peerStateDetailOutput `json:"details" yaml:"details"`
}
type signalStateOutput struct {
URL string `json:"url" yaml:"url"`
Connected bool `json:"connected" yaml:"connected"`
}
type managementStateOutput struct {
URL string `json:"url" yaml:"url"`
Connected bool `json:"connected" yaml:"connected"`
}
type statusOutputOverview struct {
Peers peersStateOutput `json:"peers" yaml:"peers"`
CliVersion string `json:"cliVersion" yaml:"cliVersion"`
DaemonVersion string `json:"daemonVersion" yaml:"daemonVersion"`
DaemonStatus string `json:"daemonStatus" yaml:"daemonStatus"`
ManagementState managementStateOutput `json:"management" yaml:"management"`
SignalState signalStateOutput `json:"signal" yaml:"signal"`
IP string `json:"ip" yaml:"ip"`
PubKey string `json:"publicKey" yaml:"publicKey"`
KernelInterface string `json:"interfaceType" yaml:"interfaceType"`
FQDN string `json:"domain" yaml:"domain"`
}
var (
detailFlag bool
ipv4Flag bool
@ -64,9 +106,56 @@ func statusFunc(cmd *cobra.Command, args []string) error {
ctx := internal.CtxInitState(context.Background())
resp, _ := getStatus(ctx, cmd)
if err != nil {
return nil
}
if resp.GetStatus() == string(internal.StatusNeedsLogin) || resp.GetStatus() == string(internal.StatusLoginFailed) {
cmd.Printf("Daemon status: %s\n\n"+
"Run UP command to log in with SSO (interactive login):\n\n"+
" netbird up \n\n"+
"If you are running a self-hosted version and no SSO provider has been configured in your Management Server,\n"+
"you can use a setup-key:\n\n netbird up --management-url <YOUR_MANAGEMENT_URL> --setup-key <YOUR_SETUP_KEY>\n\n"+
"More info: https://www.netbird.io/docs/overview/setup-keys\n\n",
resp.GetStatus(),
)
return nil
}
if ipv4Flag {
cmd.Print(parseInterfaceIP(resp.GetFullStatus().GetLocalPeerState().GetIP()))
return nil
}
statusOutputOverview := convertToStatusOutputOverview(resp)
statusOutputString := ""
if detailFlag {
statusOutputString = parseToFullDetailSummary(statusOutputOverview)
} else if jsonFlag {
statusOutputString, err = parseToJson(statusOutputOverview)
if err != nil {
return err
}
} else if yamlFlag {
statusOutputString, err = parseToYaml(statusOutputOverview)
if err != nil {
return err
}
} else {
statusOutputString = parseGeneralSummary(statusOutputOverview, false)
}
cmd.Print(statusOutputString)
return nil
}
func getStatus(ctx context.Context, cmd *cobra.Command) (*proto.StatusResponse, error) {
conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil {
return fmt.Errorf("failed to connect to daemon error: %v\n"+
return nil, fmt.Errorf("failed to connect to daemon error: %v\n"+
"If the daemon is not running please run: "+
"\nnetbird service install \nnetbird service start\n", err)
}
@ -74,49 +163,10 @@ func statusFunc(cmd *cobra.Command, args []string) error {
resp, err := proto.NewDaemonServiceClient(conn).Status(cmd.Context(), &proto.StatusRequest{GetFullPeerStatus: true})
if err != nil {
return fmt.Errorf("status failed: %v", status.Convert(err).Message())
return nil, fmt.Errorf("status failed: %v", status.Convert(err).Message())
}
daemonStatus := fmt.Sprintf("Daemon status: %s\n", resp.GetStatus())
if resp.GetStatus() == string(internal.StatusNeedsLogin) || resp.GetStatus() == string(internal.StatusLoginFailed) {
cmd.Printf("%s\n"+
"Run UP command to log in with SSO (interactive login):\n\n"+
" netbird up \n\n"+
"If you are running a self-hosted version and no SSO provider has been configured in your Management Server,\n"+
"you can use a setup-key:\n\n netbird up --management-url <YOUR_MANAGEMENT_URL> --setup-key <YOUR_SETUP_KEY>\n\n"+
"More info: https://www.netbird.io/docs/overview/setup-keys\n\n",
daemonStatus,
)
return nil
}
pbFullStatus := resp.GetFullStatus()
fullStatus := fromProtoFullStatus(pbFullStatus)
statusOutputString := ""
if detailFlag {
statusOutputString = parseToHumanReadable(fullStatus, daemonStatus, resp.GetDaemonVersion())
}
if jsonFlag {
statusOutputString, err = parseToJson(fullStatus)
if err != nil {
return fmt.Errorf("json marshal failed")
}
}
if yamlFlag {
statusOutputString, err = parseToYaml(fullStatus)
if err != nil {
return fmt.Errorf("yaml marshal failed")
}
}
if ipv4Flag {
statusOutputString = parseInterfaceIP(fullStatus.LocalPeerState.IP)
}
cmd.Print(statusOutputString)
return nil
return resp, nil
}
func parseFilters() error {
@ -138,43 +188,104 @@ func parseFilters() error {
return nil
}
func fromProtoFullStatus(pbFullStatus *proto.FullStatus) nbStatus.FullStatus {
var fullStatus nbStatus.FullStatus
func convertToStatusOutputOverview(resp *proto.StatusResponse) statusOutputOverview {
pbFullStatus := resp.GetFullStatus()
managementState := pbFullStatus.GetManagementState()
fullStatus.ManagementState.URL = managementState.GetURL()
fullStatus.ManagementState.Connected = managementState.GetConnected()
managementOverview := managementStateOutput{
URL: managementState.GetURL(),
Connected: managementState.GetConnected(),
}
signalState := pbFullStatus.GetSignalState()
fullStatus.SignalState.URL = signalState.GetURL()
fullStatus.SignalState.Connected = signalState.GetConnected()
signalOverview := signalStateOutput{
URL: signalState.GetURL(),
Connected: signalState.GetConnected(),
}
localPeerState := pbFullStatus.GetLocalPeerState()
fullStatus.LocalPeerState.IP = localPeerState.GetIP()
fullStatus.LocalPeerState.PubKey = localPeerState.GetPubKey()
fullStatus.LocalPeerState.KernelInterface = localPeerState.GetKernelInterface()
fullStatus.LocalPeerState.FQDN = localPeerState.GetFqdn()
peersOverview := mapPeers(resp.GetFullStatus().GetPeers())
var peersState []nbStatus.PeerState
interfaceTypeString := "Userspace"
interfaceIP := pbFullStatus.GetLocalPeerState().GetIP()
if pbFullStatus.LocalPeerState.KernelInterface {
interfaceTypeString = "Kernel"
} else if pbFullStatus.LocalPeerState.IP == "" {
interfaceTypeString = "N/A"
interfaceIP = "N/A"
}
overview := statusOutputOverview{
Peers: peersOverview,
CliVersion: system.NetbirdVersion(),
DaemonVersion: resp.GetDaemonVersion(),
DaemonStatus: resp.GetStatus(),
ManagementState: managementOverview,
SignalState: signalOverview,
IP: interfaceIP,
PubKey: pbFullStatus.GetLocalPeerState().GetPubKey(),
KernelInterface: interfaceTypeString,
FQDN: pbFullStatus.GetLocalPeerState().GetFqdn(),
}
return overview
}
func mapPeers(peers []*proto.PeerState) peersStateOutput {
var peersStateDetail []peerStateDetailOutput
localICE := "-"
remoteICE := "-"
connType := "-"
peersConnected := 0
for _, pbPeerState := range peers {
isPeerConnected := pbPeerState.ConnStatus == peer.StatusConnected.String()
if skipDetailByFilters(pbPeerState, isPeerConnected) {
continue
}
if isPeerConnected {
peersConnected = peersConnected + 1
localICE = pbPeerState.GetLocalIceCandidateType()
remoteICE = pbPeerState.GetRemoteIceCandidateType()
connType = "P2P"
if pbPeerState.Relayed {
connType = "Relayed"
}
}
for _, pbPeerState := range pbFullStatus.GetPeers() {
timeLocal := pbPeerState.GetConnStatusUpdate().AsTime().Local()
peerState := nbStatus.PeerState{
peerState := peerStateDetailOutput{
IP: pbPeerState.GetIP(),
PubKey: pbPeerState.GetPubKey(),
ConnStatus: pbPeerState.GetConnStatus(),
ConnStatusUpdate: timeLocal,
Relayed: pbPeerState.GetRelayed(),
ConnStatusUpdate: timeLocal.UTC(),
ConnType: connType,
Direct: pbPeerState.GetDirect(),
LocalIceCandidateType: pbPeerState.GetLocalIceCandidateType(),
RemoteIceCandidateType: pbPeerState.GetRemoteIceCandidateType(),
LocalIceCandidateType: localICE,
RemoteIceCandidateType: remoteICE,
FQDN: pbPeerState.GetFqdn(),
}
peersState = append(peersState, peerState)
peersStateDetail = append(peersStateDetail, peerState)
}
fullStatus.Peers = peersState
sortPeersByIp(peersStateDetail)
return fullStatus
peersOverview := peersStateOutput{
Total: len(peersStateDetail),
Connected: peersConnected,
Details: peersStateDetail,
}
return peersOverview
}
func sortPeersByIp(peersStateDetail []peerStateDetailOutput) {
if len(peersStateDetail) > 0 {
sort.SliceStable(peersStateDetail, func(i, j int) bool {
iAddr, _ := netip.ParseAddr(peersStateDetail[i].IP)
jAddr, _ := netip.ParseAddr(peersStateDetail[j].IP)
return iAddr.Compare(jAddr) == -1
})
}
}
func parseInterfaceIP(interfaceIP string) string {
@ -185,81 +296,68 @@ func parseInterfaceIP(interfaceIP string) string {
return fmt.Sprintf("%s\n", ip)
}
func parseToJson(fullStatus nbStatus.FullStatus) (string, error) {
jsonBytes, err := json.Marshal(fullStatus)
func parseToJson(overview statusOutputOverview) (string, error) {
jsonBytes, err := json.Marshal(overview)
if err != nil {
return "", fmt.Errorf("json marshal failed")
}
return string(jsonBytes), err
}
func parseToYaml(fullStatus nbStatus.FullStatus) (string, error) {
yamlBytes, err := yaml2.Marshal(fullStatus)
return string(yamlBytes), err
}
func countConnectedPeers(peers []nbStatus.PeerState) int {
peersConnected := 0
for _, peerState := range peers {
if peerState.ConnStatus == peer.StatusConnected.String() {
peersConnected = peersConnected + 1
}
func parseToYaml(overview statusOutputOverview) (string, error) {
yamlBytes, err := yaml.Marshal(overview)
if err != nil {
return "", fmt.Errorf("yaml marshal failed")
}
return peersConnected
return string(yamlBytes), nil
}
func parseGeneralSummary(fullStatus nbStatus.FullStatus, daemonStatus string, daemonVersion string) string {
managementStatusURL := fmt.Sprintf(" to %s", fullStatus.ManagementState.URL)
signalStatusURL := fmt.Sprintf(" to %s", fullStatus.SignalState.URL)
func parseGeneralSummary(overview statusOutputOverview, showUrl bool) string {
managementConnString := "Disconnected"
if fullStatus.ManagementState.Connected {
if overview.ManagementState.Connected {
managementConnString = "Connected"
if showUrl {
managementConnString = fmt.Sprintf("%s to %s", managementConnString, overview.ManagementState.URL)
}
}
signalConnString := "Disconnected"
if fullStatus.SignalState.Connected {
if overview.SignalState.Connected {
signalConnString = "Connected"
if showUrl {
signalConnString = fmt.Sprintf("%s to %s", signalConnString, overview.SignalState.URL)
}
}
interfaceTypeString := "Userspace"
interfaceIP := ""
if fullStatus.LocalPeerState.KernelInterface {
interfaceTypeString = "Kernel"
} else if fullStatus.LocalPeerState.IP == "" {
interfaceTypeString = "N/A"
interfaceIP = "N/A"
}
peersConnected := countConnectedPeers(fullStatus.Peers)
peersCountString := fmt.Sprintf("%d/%d Connected", peersConnected, len(fullStatus.Peers))
peersCountString := fmt.Sprintf("%d/%d Connected", overview.Peers.Connected, overview.Peers.Total)
summary := fmt.Sprintf(
"Daemon version: %s\n"+
"CLI version: %s\n"+
"%s"+ // daemon status
"Management: %s%s\n"+
"Signal: %s%s\n"+
"Management: %s\n"+
"Signal: %s\n"+
"Domain: %s\n"+
"NetBird IP: %s\n"+
"Interface type: %s\n"+
"Peers count: %s\n",
daemonVersion,
overview.DaemonVersion,
system.NetbirdVersion(),
daemonStatus,
overview.DaemonStatus,
managementConnString,
managementStatusURL,
signalConnString,
signalStatusURL,
fullStatus.LocalPeerState.FQDN,
interfaceIP,
interfaceTypeString,
overview.FQDN,
overview.IP,
overview.KernelInterface,
peersCountString,
)
return summary
}
func parseToHumanReadable(fullStatus nbStatus.FullStatus, daemonStatus string, daemonVersion string) string {
parsedPeersString := parsePeers(fullStatus.Peers)
summary := parseGeneralSummary(fullStatus, daemonStatus, daemonVersion)
func parseToFullDetailSummary(overview statusOutputOverview) string {
parsedPeersString := parsePeers(overview.Peers)
summary := parseGeneralSummary(overview, true)
return fmt.Sprintf(
"Peers detail:"+
@ -270,38 +368,12 @@ func parseToHumanReadable(fullStatus nbStatus.FullStatus, daemonStatus string, d
)
}
func parsePeers(peers []nbStatus.PeerState) string {
func parsePeers(peers peersStateOutput) string {
var (
peersString = ""
)
if len(peers) > 0 {
sort.SliceStable(peers, func(i, j int) bool {
iAddr, _ := netip.ParseAddr(peers[i].IP)
jAddr, _ := netip.ParseAddr(peers[j].IP)
return iAddr.Compare(jAddr) == -1
})
}
for _, peerState := range peers {
peerConnectionStatus := peerState.ConnStatus == peer.StatusConnected.String()
if skipDetailByFilters(peerState, peerConnectionStatus) {
continue
}
localICE := "-"
remoteICE := "-"
connType := "-"
if peerConnectionStatus {
localICE = peerState.LocalIceCandidateType
remoteICE = peerState.RemoteIceCandidateType
connType = "P2P"
if peerState.Relayed {
connType = "Relayed"
}
}
for _, peerState := range peers.Details {
peerString := fmt.Sprintf(
"\n %s:\n"+
" NetBird IP: %s\n"+
@ -316,10 +388,10 @@ func parsePeers(peers []nbStatus.PeerState) string {
peerState.IP,
peerState.PubKey,
peerState.ConnStatus,
connType,
peerState.ConnType,
peerState.Direct,
localICE,
remoteICE,
peerState.LocalIceCandidateType,
peerState.RemoteIceCandidateType,
peerState.ConnStatusUpdate.Format("2006-01-02 15:04:05"),
)
@ -328,7 +400,7 @@ func parsePeers(peers []nbStatus.PeerState) string {
return peersString
}
func skipDetailByFilters(peerState nbStatus.PeerState, isConnected bool) bool {
func skipDetailByFilters(peerState *proto.PeerState, isConnected bool) bool {
statusEval := false
ipEval := false

View File

@ -1,134 +1,292 @@
package cmd
import (
nbStatus "github.com/netbirdio/netbird/client/status"
"github.com/stretchr/testify/assert"
"testing"
"time"
"github.com/stretchr/testify/assert"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/netbirdio/netbird/client/proto"
"github.com/netbirdio/netbird/client/system"
)
var fullStatus = nbStatus.FullStatus{
Peers: []nbStatus.PeerState{
{
IP: "192.168.178.101",
PubKey: "Pubkey1",
FQDN: "peer-1.awesome-domain.com",
ConnStatus: "Connected",
ConnStatusUpdate: time.Date(2001, time.Month(1), 1, 1, 1, 1, 0, time.UTC),
Relayed: false,
LocalIceCandidateType: "-",
RemoteIceCandidateType: "-",
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: "-",
},
{
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: "-",
RemoteIceCandidateType: "-",
},
},
{
IP: "192.168.178.102",
PubKey: "Pubkey2",
FQDN: "peer-2.awesome-domain.com",
ConnStatus: "Connected",
ConnStatusUpdate: time.Date(2002, time.Month(2), 2, 2, 2, 2, 0, time.UTC),
Relayed: false,
LocalIceCandidateType: "-",
RemoteIceCandidateType: "-",
ManagementState: &proto.ManagementState{
URL: "my-awesome-management.com:443",
Connected: true,
},
SignalState: &proto.SignalState{
URL: "my-awesome-signal.com:443",
Connected: true,
},
LocalPeerState: &proto.LocalPeerState{
IP: "192.168.178.100/16",
PubKey: "Some-Pub-Key",
KernelInterface: true,
Fqdn: "some-localhost.awesome-domain.com",
},
},
ManagementState: nbStatus.ManagementState{
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",
ConnStatus: "Connected",
ConnStatusUpdate: time.Date(2001, 1, 1, 1, 1, 1, 0, time.UTC),
ConnType: "P2P",
Direct: true,
LocalIceCandidateType: "-",
RemoteIceCandidateType: "-",
},
{
IP: "192.168.178.102",
PubKey: "Pubkey2",
FQDN: "peer-2.awesome-domain.com",
ConnStatus: "Connected",
ConnStatusUpdate: time.Date(2002, 2, 2, 2, 2, 2, 0, time.UTC),
ConnType: "Relayed",
Direct: false,
LocalIceCandidateType: "-",
RemoteIceCandidateType: "-",
},
},
},
CliVersion: system.NetbirdVersion(),
DaemonVersion: "0.14.1",
DaemonStatus: "Connected",
ManagementState: managementStateOutput{
URL: "my-awesome-management.com:443",
Connected: true,
},
SignalState: nbStatus.SignalState{
SignalState: signalStateOutput{
URL: "my-awesome-signal.com:443",
Connected: true,
},
LocalPeerState: nbStatus.LocalPeerState{
IP: "192.168.178.2",
PubKey: "Some-Pub-Key",
KernelInterface: false,
FQDN: "some-localhost.awesome-domain.com",
},
IP: "192.168.178.100/16",
PubKey: "Some-Pub-Key",
KernelInterface: "Kernel",
FQDN: "some-localhost.awesome-domain.com",
}
// @formatter:off
func TestParsingToJson(t *testing.T) {
json, _ := parseToJson(fullStatus)
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) {
json, _ := parseToJson(overview)
// @formatter:off
expectedJson := "{" +
"\"Peers\":" +
"\"peers\":" +
"{" +
"\"total\":2," +
"\"connected\":2," +
"\"details\":" +
"[" +
"{" +
"\"IP\":\"192.168.178.101\"," +
"\"PubKey\":\"Pubkey1\"," +
"\"FQDN\":\"peer-1.awesome-domain.com\"," +
"\"ConnStatus\":\"Connected\"," +
"\"ConnStatusUpdate\":\"2001-01-01T01:01:01Z\"," +
"\"Relayed\":false," +
"\"Direct\":false," +
"\"LocalIceCandidateType\":\"-\"," +
"\"RemoteIceCandidateType\":\"-\"" +
"\"ip\":\"192.168.178.101\"," +
"\"publicKey\":\"Pubkey1\"," +
"\"fqdn\":\"peer-1.awesome-domain.com\"," +
"\"connectionStatus\":\"Connected\"" +
",\"connectionStatusUpdate\":\"2001-01-01T01:01:01Z\"," +
"\"connectionType\":\"P2P\"," +
"\"direct\":true," +
"\"localIceCandidateType\":\"-\"," +
"\"remoteIceCandidateType\":\"-\"" +
"}," +
"{" +
"\"IP\":\"192.168.178.102\"," +
"\"PubKey\":\"Pubkey2\"," +
"\"FQDN\":\"peer-2.awesome-domain.com\"," +
"\"ConnStatus\":\"Connected\"," +
"\"ConnStatusUpdate\":\"2002-02-02T02:02:02Z\"," +
"\"Relayed\":false," +
"\"Direct\":false," +
"\"LocalIceCandidateType\":\"-\"," +
"\"RemoteIceCandidateType\":\"-\"" +
"\"ip\":\"192.168.178.102\"," +
"\"publicKey\":\"Pubkey2\"," +
"\"fqdn\":\"peer-2.awesome-domain.com\"," +
"\"connectionStatus\":\"Connected\"," +
"\"connectionStatusUpdate\":\"2002-02-02T02:02:02Z\"," +
"\"connectionType\":\"Relayed\"," +
"\"direct\":false," +
"\"localIceCandidateType\":\"-\"," +
"\"remoteIceCandidateType\":\"-\"" +
"}" +
"]," +
"\"ManagementState\":" +
"{" +
"\"URL\":\"my-awesome-management.com:443\"," +
"\"Connected\":true" +
"]" +
"}," +
"\"SignalState\":" +
"\"cliVersion\":\"development\"," +
"\"daemonVersion\":\"0.14.1\"," +
"\"daemonStatus\":\"Connected\"," +
"\"management\":" +
"{" +
"\"URL\":\"my-awesome-signal.com:443\"," +
"\"Connected\":true" +
"\"url\":\"my-awesome-management.com:443\"," +
"\"connected\":true" +
"}," +
"\"LocalPeerState\":" +
"\"signal\":" +
"{" +
"\"IP\":\"192.168.178.2\"," +
"\"PubKey\":\"Some-Pub-Key\"," +
"\"KernelInterface\":false," +
"\"FQDN\":\"some-localhost.awesome-domain.com\"" +
"}" +
"\"url\":\"my-awesome-signal.com:443\"," +
"\"connected\":true" +
"}," +
"\"ip\":\"192.168.178.100/16\"," +
"\"publicKey\":\"Some-Pub-Key\"," +
"\"interfaceType\":\"Kernel\"," +
"\"domain\":\"some-localhost.awesome-domain.com\"" +
"}"
// @formatter:on
assert.Equal(t, expectedJson, json)
}
func TestParsingToYaml(t *testing.T) {
yaml, _ := parseToYaml(fullStatus)
yaml, _ := parseToYaml(overview)
expectedYaml := "peers:\n" +
"- ip: 192.168.178.101\n" +
" pubkey: Pubkey1\n" +
" fqdn: peer-1.awesome-domain.com\n" +
" connstatus: Connected\n" +
" connstatusupdate: 2001-01-01T01:01:01Z\n" +
" relayed: false\n" +
" direct: false\n" +
" localicecandidatetype: '-'\n" +
" remoteicecandidatetype: '-'\n" +
"- ip: 192.168.178.102\n" +
" pubkey: Pubkey2\n" +
" fqdn: peer-2.awesome-domain.com\n" +
" connstatus: Connected\n" +
" connstatusupdate: 2002-02-02T02:02:02Z\n" +
" relayed: false\n" +
" direct: false\n" +
" localicecandidatetype: '-'\n" +
" remoteicecandidatetype: '-'\n" +
"managementstate:\n" +
" total: 2\n" +
" connected: 2\n" +
" details:\n" +
" - ip: 192.168.178.101\n" +
" publicKey: Pubkey1\n" +
" fqdn: peer-1.awesome-domain.com\n" +
" connectionStatus: Connected\n" +
" connectionStatusUpdate: 2001-01-01T01:01:01Z\n" +
" connectionType: P2P\n" +
" direct: true\n" +
" localIceCandidateType: '-'\n" +
" remoteIceCandidateType: '-'\n" +
" - ip: 192.168.178.102\n" +
" publicKey: Pubkey2\n" +
" fqdn: peer-2.awesome-domain.com\n" +
" connectionStatus: Connected\n" +
" connectionStatusUpdate: 2002-02-02T02:02:02Z\n" +
" connectionType: Relayed\n" +
" direct: false\n" +
" localIceCandidateType: '-'\n" +
" remoteIceCandidateType: '-'\n" +
"cliVersion: development\n" +
"daemonVersion: 0.14.1\n" +
"daemonStatus: Connected\n" +
"management:\n" +
" url: my-awesome-management.com:443\n" +
" connected: true\n" +
"signalstate:\n" +
"signal:\n" +
" url: my-awesome-signal.com:443\n" +
" connected: true\n" +
"localpeerstate:\n" +
" ip: 192.168.178.2\n" +
" pubkey: Some-Pub-Key\n" +
" kernelinterface: false\n" +
" fqdn: some-localhost.awesome-domain.com\n"
"ip: 192.168.178.100/16\n" +
"publicKey: Some-Pub-Key\n" +
"interfaceType: Kernel\n" +
"domain: some-localhost.awesome-domain.com\n"
assert.Equal(t, expectedYaml, yaml)
}
func TestParsingToDetail(t *testing.T) {
detail := parseToFullDetailSummary(overview)
expectedDetail := "Peers detail:\n" +
" peer-1.awesome-domain.com:\n" +
" NetBird IP: 192.168.178.101\n" +
" Public key: Pubkey1\n" +
" Status: Connected\n" +
" -- detail --\n" +
" Connection type: P2P\n" +
" Direct: true\n" +
" ICE candidate (Local/Remote): -/-\n" +
" Last connection update: 2001-01-01 01:01:01\n" +
"\n" +
" peer-2.awesome-domain.com:\n" +
" NetBird IP: 192.168.178.102\n" +
" Public key: Pubkey2\n" +
" Status: Connected\n" +
" -- detail --\n" +
" Connection type: Relayed\n" +
" Direct: false\n" +
" ICE candidate (Local/Remote): -/-\n" +
" Last connection update: 2002-02-02 02:02:02\n" +
"\n" +
"Daemon version: 0.14.1\n" +
"CLI version: development\n" +
"ConnectedManagement: Connected to my-awesome-management.com:443\n" +
"Signal: Connected to my-awesome-signal.com:443\n" +
"Domain: some-localhost.awesome-domain.com\n" +
"NetBird IP: 192.168.178.100/16\n" +
"Interface type: Kernel\n" +
"Peers count: 2/2 Connected\n"
assert.Equal(t, expectedDetail, detail)
}
func TestParsingToShortVersion(t *testing.T) {
shortVersion := parseGeneralSummary(overview, false)
expectedString := "Daemon version: 0.14.1\n" +
"CLI version: development\n" +
"ConnectedManagement: Connected\n" +
"Signal: Connected\n" +
"Domain: some-localhost.awesome-domain.com\n" +
"NetBird IP: 192.168.178.100/16\n" +
"Interface type: Kernel\n" +
"Peers count: 2/2 Connected\n"
assert.Equal(t, expectedString, shortVersion)
}
func TestParsingOfIp(t *testing.T) {
InterfaceIp := "192.168.178.123/16"
parsedId := parseInterfaceIP(InterfaceIp)
assert.Equal(t, "192.168.178.123\n", parsedId)
}