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" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
yaml2 "gopkg.in/yaml.v2"
"net" "net"
"net/netip" "net/netip"
"sort" "sort"
"strings" "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"
"github.com/netbirdio/netbird/client/internal/peer" "github.com/netbirdio/netbird/client/internal/peer"
"github.com/netbirdio/netbird/client/proto" "github.com/netbirdio/netbird/client/proto"
nbStatus "github.com/netbirdio/netbird/client/status"
"github.com/netbirdio/netbird/client/system" "github.com/netbirdio/netbird/client/system"
"github.com/netbirdio/netbird/util" "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 ( var (
detailFlag bool detailFlag bool
ipv4Flag bool ipv4Flag bool
@ -64,9 +106,56 @@ func statusFunc(cmd *cobra.Command, args []string) error {
ctx := internal.CtxInitState(context.Background()) 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) conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil { 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: "+ "If the daemon is not running please run: "+
"\nnetbird service install \nnetbird service start\n", err) "\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}) resp, err := proto.NewDaemonServiceClient(conn).Status(cmd.Context(), &proto.StatusRequest{GetFullPeerStatus: true})
if err != nil { 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()) return resp, nil
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
} }
func parseFilters() error { func parseFilters() error {
@ -138,43 +188,104 @@ func parseFilters() error {
return nil return nil
} }
func fromProtoFullStatus(pbFullStatus *proto.FullStatus) nbStatus.FullStatus { func convertToStatusOutputOverview(resp *proto.StatusResponse) statusOutputOverview {
var fullStatus nbStatus.FullStatus pbFullStatus := resp.GetFullStatus()
managementState := pbFullStatus.GetManagementState() managementState := pbFullStatus.GetManagementState()
fullStatus.ManagementState.URL = managementState.GetURL() managementOverview := managementStateOutput{
fullStatus.ManagementState.Connected = managementState.GetConnected() URL: managementState.GetURL(),
Connected: managementState.GetConnected(),
}
signalState := pbFullStatus.GetSignalState() signalState := pbFullStatus.GetSignalState()
fullStatus.SignalState.URL = signalState.GetURL() signalOverview := signalStateOutput{
fullStatus.SignalState.Connected = signalState.GetConnected() URL: signalState.GetURL(),
Connected: signalState.GetConnected(),
}
localPeerState := pbFullStatus.GetLocalPeerState() peersOverview := mapPeers(resp.GetFullStatus().GetPeers())
fullStatus.LocalPeerState.IP = localPeerState.GetIP()
fullStatus.LocalPeerState.PubKey = localPeerState.GetPubKey()
fullStatus.LocalPeerState.KernelInterface = localPeerState.GetKernelInterface()
fullStatus.LocalPeerState.FQDN = localPeerState.GetFqdn()
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() timeLocal := pbPeerState.GetConnStatusUpdate().AsTime().Local()
peerState := nbStatus.PeerState{ peerState := peerStateDetailOutput{
IP: pbPeerState.GetIP(), IP: pbPeerState.GetIP(),
PubKey: pbPeerState.GetPubKey(), PubKey: pbPeerState.GetPubKey(),
ConnStatus: pbPeerState.GetConnStatus(), ConnStatus: pbPeerState.GetConnStatus(),
ConnStatusUpdate: timeLocal, ConnStatusUpdate: timeLocal.UTC(),
Relayed: pbPeerState.GetRelayed(), ConnType: connType,
Direct: pbPeerState.GetDirect(), Direct: pbPeerState.GetDirect(),
LocalIceCandidateType: pbPeerState.GetLocalIceCandidateType(), LocalIceCandidateType: localICE,
RemoteIceCandidateType: pbPeerState.GetRemoteIceCandidateType(), RemoteIceCandidateType: remoteICE,
FQDN: pbPeerState.GetFqdn(), 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 { func parseInterfaceIP(interfaceIP string) string {
@ -185,81 +296,68 @@ func parseInterfaceIP(interfaceIP string) string {
return fmt.Sprintf("%s\n", ip) return fmt.Sprintf("%s\n", ip)
} }
func parseToJson(fullStatus nbStatus.FullStatus) (string, error) { func parseToJson(overview statusOutputOverview) (string, error) {
jsonBytes, err := json.Marshal(fullStatus) jsonBytes, err := json.Marshal(overview)
if err != nil {
return "", fmt.Errorf("json marshal failed")
}
return string(jsonBytes), err return string(jsonBytes), err
} }
func parseToYaml(fullStatus nbStatus.FullStatus) (string, error) { func parseToYaml(overview statusOutputOverview) (string, error) {
yamlBytes, err := yaml2.Marshal(fullStatus) yamlBytes, err := yaml.Marshal(overview)
return string(yamlBytes), err if err != nil {
} return "", fmt.Errorf("yaml marshal failed")
func countConnectedPeers(peers []nbStatus.PeerState) int {
peersConnected := 0
for _, peerState := range peers {
if peerState.ConnStatus == peer.StatusConnected.String() {
peersConnected = peersConnected + 1
}
} }
return peersConnected return string(yamlBytes), nil
} }
func parseGeneralSummary(fullStatus nbStatus.FullStatus, daemonStatus string, daemonVersion string) string { func parseGeneralSummary(overview statusOutputOverview, showUrl bool) string {
managementStatusURL := fmt.Sprintf(" to %s", fullStatus.ManagementState.URL)
signalStatusURL := fmt.Sprintf(" to %s", fullStatus.SignalState.URL)
managementConnString := "Disconnected" managementConnString := "Disconnected"
if fullStatus.ManagementState.Connected { if overview.ManagementState.Connected {
managementConnString = "Connected" managementConnString = "Connected"
if showUrl {
managementConnString = fmt.Sprintf("%s to %s", managementConnString, overview.ManagementState.URL)
}
} }
signalConnString := "Disconnected" signalConnString := "Disconnected"
if fullStatus.SignalState.Connected { if overview.SignalState.Connected {
signalConnString = "Connected" signalConnString = "Connected"
if showUrl {
signalConnString = fmt.Sprintf("%s to %s", signalConnString, overview.SignalState.URL)
}
} }
interfaceTypeString := "Userspace" peersCountString := fmt.Sprintf("%d/%d Connected", overview.Peers.Connected, overview.Peers.Total)
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))
summary := fmt.Sprintf( summary := fmt.Sprintf(
"Daemon version: %s\n"+ "Daemon version: %s\n"+
"CLI version: %s\n"+ "CLI version: %s\n"+
"%s"+ // daemon status "%s"+ // daemon status
"Management: %s%s\n"+ "Management: %s\n"+
"Signal: %s%s\n"+ "Signal: %s\n"+
"Domain: %s\n"+ "Domain: %s\n"+
"NetBird IP: %s\n"+ "NetBird IP: %s\n"+
"Interface type: %s\n"+ "Interface type: %s\n"+
"Peers count: %s\n", "Peers count: %s\n",
daemonVersion, overview.DaemonVersion,
system.NetbirdVersion(), system.NetbirdVersion(),
daemonStatus, overview.DaemonStatus,
managementConnString, managementConnString,
managementStatusURL,
signalConnString, signalConnString,
signalStatusURL, overview.FQDN,
fullStatus.LocalPeerState.FQDN, overview.IP,
interfaceIP, overview.KernelInterface,
interfaceTypeString,
peersCountString, peersCountString,
) )
return summary return summary
} }
func parseToHumanReadable(fullStatus nbStatus.FullStatus, daemonStatus string, daemonVersion string) string { func parseToFullDetailSummary(overview statusOutputOverview) string {
parsedPeersString := parsePeers(fullStatus.Peers) parsedPeersString := parsePeers(overview.Peers)
summary := parseGeneralSummary(fullStatus, daemonStatus, daemonVersion) summary := parseGeneralSummary(overview, true)
return fmt.Sprintf( return fmt.Sprintf(
"Peers detail:"+ "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 ( var (
peersString = "" peersString = ""
) )
if len(peers) > 0 { for _, peerState := range peers.Details {
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"
}
}
peerString := fmt.Sprintf( peerString := fmt.Sprintf(
"\n %s:\n"+ "\n %s:\n"+
" NetBird IP: %s\n"+ " NetBird IP: %s\n"+
@ -316,10 +388,10 @@ func parsePeers(peers []nbStatus.PeerState) string {
peerState.IP, peerState.IP,
peerState.PubKey, peerState.PubKey,
peerState.ConnStatus, peerState.ConnStatus,
connType, peerState.ConnType,
peerState.Direct, peerState.Direct,
localICE, peerState.LocalIceCandidateType,
remoteICE, peerState.RemoteIceCandidateType,
peerState.ConnStatusUpdate.Format("2006-01-02 15:04:05"), peerState.ConnStatusUpdate.Format("2006-01-02 15:04:05"),
) )
@ -328,7 +400,7 @@ func parsePeers(peers []nbStatus.PeerState) string {
return peersString return peersString
} }
func skipDetailByFilters(peerState nbStatus.PeerState, isConnected bool) bool { func skipDetailByFilters(peerState *proto.PeerState, isConnected bool) bool {
statusEval := false statusEval := false
ipEval := false ipEval := false

View File

@ -1,134 +1,292 @@
package cmd package cmd
import ( import (
nbStatus "github.com/netbirdio/netbird/client/status"
"github.com/stretchr/testify/assert"
"testing" "testing"
"time" "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{ var resp = &proto.StatusResponse{
Peers: []nbStatus.PeerState{ Status: "Connected",
{ FullStatus: &proto.FullStatus{
IP: "192.168.178.101", Peers: []*proto.PeerState{
PubKey: "Pubkey1", {
FQDN: "peer-1.awesome-domain.com", IP: "192.168.178.101",
ConnStatus: "Connected", PubKey: "Pubkey1",
ConnStatusUpdate: time.Date(2001, time.Month(1), 1, 1, 1, 1, 0, time.UTC), Fqdn: "peer-1.awesome-domain.com",
Relayed: false, ConnStatus: "Connected",
LocalIceCandidateType: "-", ConnStatusUpdate: timestamppb.New(time.Date(2001, time.Month(1), 1, 1, 1, 1, 0, time.UTC)),
RemoteIceCandidateType: "-", 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: "-",
},
}, },
{ ManagementState: &proto.ManagementState{
IP: "192.168.178.102", URL: "my-awesome-management.com:443",
PubKey: "Pubkey2", Connected: true,
FQDN: "peer-2.awesome-domain.com", },
ConnStatus: "Connected", SignalState: &proto.SignalState{
ConnStatusUpdate: time.Date(2002, time.Month(2), 2, 2, 2, 2, 0, time.UTC), URL: "my-awesome-signal.com:443",
Relayed: false, Connected: true,
LocalIceCandidateType: "-", },
RemoteIceCandidateType: "-", 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", URL: "my-awesome-management.com:443",
Connected: true, Connected: true,
}, },
SignalState: nbStatus.SignalState{ SignalState: signalStateOutput{
URL: "my-awesome-signal.com:443", URL: "my-awesome-signal.com:443",
Connected: true, Connected: true,
}, },
LocalPeerState: nbStatus.LocalPeerState{ IP: "192.168.178.100/16",
IP: "192.168.178.2", PubKey: "Some-Pub-Key",
PubKey: "Some-Pub-Key", KernelInterface: "Kernel",
KernelInterface: false, FQDN: "some-localhost.awesome-domain.com",
FQDN: "some-localhost.awesome-domain.com",
},
} }
// @formatter:off func TestConversionFromFullStatusToOutputOverview(t *testing.T) {
func TestParsingToJson(t *testing.T) { convertedResult := convertToStatusOutputOverview(resp)
json, _ := parseToJson(fullStatus)
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 := "{" + expectedJson := "{" +
"\"Peers\":" + "\"peers\":" +
"{" +
"\"total\":2," +
"\"connected\":2," +
"\"details\":" +
"[" + "[" +
"{" + "{" +
"\"IP\":\"192.168.178.101\"," + "\"ip\":\"192.168.178.101\"," +
"\"PubKey\":\"Pubkey1\"," + "\"publicKey\":\"Pubkey1\"," +
"\"FQDN\":\"peer-1.awesome-domain.com\"," + "\"fqdn\":\"peer-1.awesome-domain.com\"," +
"\"ConnStatus\":\"Connected\"," + "\"connectionStatus\":\"Connected\"" +
"\"ConnStatusUpdate\":\"2001-01-01T01:01:01Z\"," + ",\"connectionStatusUpdate\":\"2001-01-01T01:01:01Z\"," +
"\"Relayed\":false," + "\"connectionType\":\"P2P\"," +
"\"Direct\":false," + "\"direct\":true," +
"\"LocalIceCandidateType\":\"-\"," + "\"localIceCandidateType\":\"-\"," +
"\"RemoteIceCandidateType\":\"-\"" + "\"remoteIceCandidateType\":\"-\"" +
"}," + "}," +
"{" + "{" +
"\"IP\":\"192.168.178.102\"," + "\"ip\":\"192.168.178.102\"," +
"\"PubKey\":\"Pubkey2\"," + "\"publicKey\":\"Pubkey2\"," +
"\"FQDN\":\"peer-2.awesome-domain.com\"," + "\"fqdn\":\"peer-2.awesome-domain.com\"," +
"\"ConnStatus\":\"Connected\"," + "\"connectionStatus\":\"Connected\"," +
"\"ConnStatusUpdate\":\"2002-02-02T02:02:02Z\"," + "\"connectionStatusUpdate\":\"2002-02-02T02:02:02Z\"," +
"\"Relayed\":false," + "\"connectionType\":\"Relayed\"," +
"\"Direct\":false," + "\"direct\":false," +
"\"LocalIceCandidateType\":\"-\"," + "\"localIceCandidateType\":\"-\"," +
"\"RemoteIceCandidateType\":\"-\"" + "\"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\"," + "\"url\":\"my-awesome-management.com:443\"," +
"\"Connected\":true" + "\"connected\":true" +
"}," + "}," +
"\"LocalPeerState\":" + "\"signal\":" +
"{" + "{" +
"\"IP\":\"192.168.178.2\"," + "\"url\":\"my-awesome-signal.com:443\"," +
"\"PubKey\":\"Some-Pub-Key\"," + "\"connected\":true" +
"\"KernelInterface\":false," + "}," +
"\"FQDN\":\"some-localhost.awesome-domain.com\"" + "\"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) assert.Equal(t, expectedJson, json)
} }
func TestParsingToYaml(t *testing.T) { func TestParsingToYaml(t *testing.T) {
yaml, _ := parseToYaml(fullStatus) yaml, _ := parseToYaml(overview)
expectedYaml := "peers:\n" + expectedYaml := "peers:\n" +
"- ip: 192.168.178.101\n" + " total: 2\n" +
" pubkey: Pubkey1\n" + " connected: 2\n" +
" fqdn: peer-1.awesome-domain.com\n" + " details:\n" +
" connstatus: Connected\n" + " - ip: 192.168.178.101\n" +
" connstatusupdate: 2001-01-01T01:01:01Z\n" + " publicKey: Pubkey1\n" +
" relayed: false\n" + " fqdn: peer-1.awesome-domain.com\n" +
" direct: false\n" + " connectionStatus: Connected\n" +
" localicecandidatetype: '-'\n" + " connectionStatusUpdate: 2001-01-01T01:01:01Z\n" +
" remoteicecandidatetype: '-'\n" + " connectionType: P2P\n" +
"- ip: 192.168.178.102\n" + " direct: true\n" +
" pubkey: Pubkey2\n" + " localIceCandidateType: '-'\n" +
" fqdn: peer-2.awesome-domain.com\n" + " remoteIceCandidateType: '-'\n" +
" connstatus: Connected\n" + " - ip: 192.168.178.102\n" +
" connstatusupdate: 2002-02-02T02:02:02Z\n" + " publicKey: Pubkey2\n" +
" relayed: false\n" + " fqdn: peer-2.awesome-domain.com\n" +
" direct: false\n" + " connectionStatus: Connected\n" +
" localicecandidatetype: '-'\n" + " connectionStatusUpdate: 2002-02-02T02:02:02Z\n" +
" remoteicecandidatetype: '-'\n" + " connectionType: Relayed\n" +
"managementstate:\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" + " url: my-awesome-management.com:443\n" +
" connected: true\n" + " connected: true\n" +
"signalstate:\n" + "signal:\n" +
" url: my-awesome-signal.com:443\n" + " url: my-awesome-signal.com:443\n" +
" connected: true\n" + " connected: true\n" +
"localpeerstate:\n" + "ip: 192.168.178.100/16\n" +
" ip: 192.168.178.2\n" + "publicKey: Some-Pub-Key\n" +
" pubkey: Some-Pub-Key\n" + "interfaceType: Kernel\n" +
" kernelinterface: false\n" + "domain: some-localhost.awesome-domain.com\n"
" fqdn: some-localhost.awesome-domain.com\n"
assert.Equal(t, expectedYaml, yaml) 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)
}