Json list output for network, profiles etc

This commit is contained in:
TechHutTV
2026-05-19 15:46:31 -07:00
parent a212963dac
commit d3293fb282
6 changed files with 332 additions and 9 deletions

View File

@@ -8,6 +8,7 @@ import (
"google.golang.org/grpc/status"
"github.com/netbirdio/netbird/client/proto"
nbstatus "github.com/netbirdio/netbird/client/status"
)
var forwardingRulesCmd = &cobra.Command{
@@ -25,6 +26,12 @@ var forwardingRulesListCmd = &cobra.Command{
RunE: listForwardingRules,
}
func init() {
forwardingRulesListCmd.PersistentFlags().BoolVarP(&jsonFlag, "json", "j", false, "display command result in json format")
forwardingRulesListCmd.PersistentFlags().BoolVarP(&yamlFlag, "yaml", "y", false, "display command result in yaml format")
forwardingRulesListCmd.MarkFlagsMutuallyExclusive("json", "yaml")
}
func listForwardingRules(cmd *cobra.Command, _ []string) error {
conn, err := getClient(cmd)
if err != nil {
@@ -38,19 +45,23 @@ func listForwardingRules(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("failed to list network: %v", status.Convert(err).Message())
}
if len(resp.GetRules()) == 0 {
rules := resp.GetRules()
sortForwardingRules(rules)
if jsonFlag || yamlFlag {
return emitForwardingList(cmd, rules)
}
if len(rules) == 0 {
cmd.Println("No forwarding rules available.")
return nil
}
printForwardingRules(cmd, resp.GetRules())
printForwardingRules(cmd, rules)
return nil
}
func printForwardingRules(cmd *cobra.Command, rules []*proto.ForwardingRule) {
cmd.Println("Available forwarding rules:")
// Sort rules by translated address
func sortForwardingRules(rules []*proto.ForwardingRule) {
sort.Slice(rules, func(i, j int) bool {
if rules[i].GetTranslatedAddress() != rules[j].GetTranslatedAddress() {
return rules[i].GetTranslatedAddress() < rules[j].GetTranslatedAddress()
@@ -58,9 +69,40 @@ func printForwardingRules(cmd *cobra.Command, rules []*proto.ForwardingRule) {
if rules[i].GetProtocol() != rules[j].GetProtocol() {
return rules[i].GetProtocol() < rules[j].GetProtocol()
}
return getFirstPort(rules[i].GetDestinationPort()) < getFirstPort(rules[j].GetDestinationPort())
})
}
func emitForwardingList(cmd *cobra.Command, rules []*proto.ForwardingRule) error {
out := &nbstatus.ForwardingListOutput{Rules: make([]nbstatus.ForwardingRuleOutput, 0, len(rules))}
for _, rule := range rules {
out.Rules = append(out.Rules, nbstatus.ForwardingRuleOutput{
TranslatedAddress: rule.GetTranslatedAddress(),
TranslatedHostname: rule.GetTranslatedHostname(),
Protocol: rule.GetProtocol(),
DestinationPort: portToString(rule.GetDestinationPort()),
TranslatedPort: portToString(rule.GetTranslatedPort()),
})
}
if jsonFlag {
s, err := out.JSON()
if err != nil {
return err
}
cmd.Println(s)
return nil
}
s, err := out.YAML()
if err != nil {
return err
}
cmd.Print(s)
return nil
}
func printForwardingRules(cmd *cobra.Command, rules []*proto.ForwardingRule) {
cmd.Println("Available forwarding rules:")
var lastIP string
for _, rule := range rules {

View File

@@ -8,6 +8,7 @@ import (
"google.golang.org/grpc/status"
"github.com/netbirdio/netbird/client/proto"
nbstatus "github.com/netbirdio/netbird/client/status"
)
var appendFlag bool
@@ -48,6 +49,10 @@ var routesDeselectCmd = &cobra.Command{
func init() {
routesSelectCmd.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "Append to current network selection instead of replacing")
routesListCmd.PersistentFlags().BoolVarP(&jsonFlag, "json", "j", false, "display command result in json format")
routesListCmd.PersistentFlags().BoolVarP(&yamlFlag, "yaml", "y", false, "display command result in yaml format")
routesListCmd.MarkFlagsMutuallyExclusive("json", "yaml")
}
func networksList(cmd *cobra.Command, _ []string) error {
@@ -63,6 +68,10 @@ func networksList(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("failed to list network: %v", status.Convert(err).Message())
}
if jsonFlag || yamlFlag {
return emitNetworksList(cmd, resp)
}
if len(resp.Routes) == 0 {
cmd.Println("No networks available.")
return nil
@@ -73,6 +82,40 @@ func networksList(cmd *cobra.Command, _ []string) error {
return nil
}
func emitNetworksList(cmd *cobra.Command, resp *proto.ListNetworksResponse) error {
out := &nbstatus.NetworksListOutput{Networks: make([]nbstatus.NetworkOutput, 0, len(resp.GetRoutes()))}
for _, route := range resp.GetRoutes() {
row := nbstatus.NetworkOutput{
ID: route.GetID(),
Range: route.GetRange(),
Domains: route.GetDomains(),
Selected: route.GetSelected(),
}
if resolved := route.GetResolvedIPs(); len(resolved) > 0 {
row.ResolvedIPs = make(map[string][]string, len(resolved))
for d, ipList := range resolved {
row.ResolvedIPs[d] = ipList.GetIps()
}
}
out.Networks = append(out.Networks, row)
}
if jsonFlag {
s, err := out.JSON()
if err != nil {
return err
}
cmd.Println(s)
return nil
}
s, err := out.YAML()
if err != nil {
return err
}
cmd.Print(s)
return nil
}
func printNetworks(cmd *cobra.Command, resp *proto.ListNetworksResponse) {
cmd.Println("Available Networks:")
for _, route := range resp.Routes {

View File

@@ -11,9 +11,16 @@ import (
"github.com/netbirdio/netbird/client/internal"
"github.com/netbirdio/netbird/client/internal/profilemanager"
"github.com/netbirdio/netbird/client/proto"
nbstatus "github.com/netbirdio/netbird/client/status"
"github.com/netbirdio/netbird/util"
)
func init() {
profileListCmd.PersistentFlags().BoolVarP(&jsonFlag, "json", "j", false, "display command result in json format")
profileListCmd.PersistentFlags().BoolVarP(&yamlFlag, "yaml", "y", false, "display command result in yaml format")
profileListCmd.MarkFlagsMutuallyExclusive("json", "yaml")
}
var profileCmd = &cobra.Command{
Use: "profile",
Short: "Manage NetBird client profiles",
@@ -90,6 +97,10 @@ func listProfilesFunc(cmd *cobra.Command, _ []string) error {
return err
}
if jsonFlag || yamlFlag {
return emitProfileList(cmd, profiles.GetProfiles())
}
// list profiles, add a tick if the profile is active
cmd.Println("Found", len(profiles.Profiles), "profiles:")
for _, profile := range profiles.Profiles {
@@ -104,6 +115,31 @@ func listProfilesFunc(cmd *cobra.Command, _ []string) error {
return nil
}
func emitProfileList(cmd *cobra.Command, profiles []*proto.Profile) error {
out := &nbstatus.ProfileListOutput{Profiles: make([]nbstatus.ProfileOutput, 0, len(profiles))}
for _, p := range profiles {
out.Profiles = append(out.Profiles, nbstatus.ProfileOutput{
Name: p.GetName(),
Active: p.GetIsActive(),
})
}
if jsonFlag {
s, err := out.JSON()
if err != nil {
return err
}
cmd.Println(s)
return nil
}
s, err := out.YAML()
if err != nil {
return err
}
cmd.Print(s)
return nil
}
func addProfileFunc(cmd *cobra.Command, args []string) error {
if err := setupCmd(cmd); err != nil {
return err

View File

@@ -8,6 +8,7 @@ import (
"google.golang.org/grpc/status"
"github.com/netbirdio/netbird/client/proto"
nbstatus "github.com/netbirdio/netbird/client/status"
)
var (
@@ -75,6 +76,10 @@ func init() {
stateCleanCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Clean all states")
stateDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all states")
stateListCmd.PersistentFlags().BoolVarP(&jsonFlag, "json", "j", false, "display command result in json format")
stateListCmd.PersistentFlags().BoolVarP(&yamlFlag, "yaml", "y", false, "display command result in yaml format")
stateListCmd.MarkFlagsMutuallyExclusive("json", "yaml")
}
func stateList(cmd *cobra.Command, _ []string) error {
@@ -94,6 +99,10 @@ func stateList(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("failed to list states: %v", status.Convert(err).Message())
}
if jsonFlag || yamlFlag {
return emitStateList(cmd, resp.GetStates())
}
cmd.Printf("\nStored states:\n\n")
for _, state := range resp.States {
cmd.Printf("- %s\n", state.Name)
@@ -102,6 +111,28 @@ func stateList(cmd *cobra.Command, _ []string) error {
return nil
}
func emitStateList(cmd *cobra.Command, states []*proto.State) error {
out := &nbstatus.StateListOutput{States: make([]nbstatus.StateOutput, 0, len(states))}
for _, s := range states {
out.States = append(out.States, nbstatus.StateOutput{Name: s.GetName()})
}
if jsonFlag {
s, err := out.JSON()
if err != nil {
return err
}
cmd.Println(s)
return nil
}
s, err := out.YAML()
if err != nil {
return err
}
cmd.Print(s)
return nil
}
func stateClean(cmd *cobra.Command, args []string) error {
var stateName string
if !allFlag {

View File

@@ -3,6 +3,7 @@ package cmd
import (
"github.com/spf13/cobra"
nbstatus "github.com/netbirdio/netbird/client/status"
"github.com/netbirdio/netbird/version"
)
@@ -10,9 +11,35 @@ var (
versionCmd = &cobra.Command{
Use: "version",
Short: "Print the NetBird's client application version",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SetOut(cmd.OutOrStdout())
cmd.Println(version.NetbirdVersion())
v := version.NetbirdVersion()
switch {
case jsonFlag:
out := &nbstatus.VersionOutput{Version: v}
s, err := out.JSON()
if err != nil {
return err
}
cmd.Println(s)
case yamlFlag:
out := &nbstatus.VersionOutput{Version: v}
s, err := out.YAML()
if err != nil {
return err
}
cmd.Print(s)
default:
cmd.Println(v)
}
return nil
},
}
)
func init() {
versionCmd.PersistentFlags().BoolVarP(&jsonFlag, "json", "j", false, "display command result in json format")
versionCmd.PersistentFlags().BoolVarP(&yamlFlag, "yaml", "y", false, "display command result in yaml format")
versionCmd.MarkFlagsMutuallyExclusive("json", "yaml")
}