141 lines
3.7 KiB
Go
141 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
)
|
|
|
|
func cmdAP(args []string) error {
|
|
if len(args) == 0 {
|
|
return fmt.Errorf("ap: expected 'list' or 'get'")
|
|
}
|
|
c, err := NewClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
switch args[0] {
|
|
case "list", "ls":
|
|
return cmdAPList(c, args[1:])
|
|
case "get":
|
|
return cmdAPGet(c, args[1:])
|
|
default:
|
|
return fmt.Errorf("ap: unknown verb %q (want: list, get)", args[0])
|
|
}
|
|
}
|
|
|
|
func cmdAPList(c *Client, args []string) error {
|
|
o, _, err := parseListFlags("ap list", args)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
items, p, raw, err := c.fetchList("/access_points", o)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return emitList(items, p, raw, o, func(items []json.RawMessage) error {
|
|
tw := newTab()
|
|
fmt.Fprintln(tw, "ID\tNAME\tTOWER\tIP_ADDRESS")
|
|
for _, rm := range items {
|
|
var a AccessPoint
|
|
_ = json.Unmarshal(rm, &a)
|
|
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", a.ID, a.Name, a.Tower, a.IPAddress)
|
|
}
|
|
return tw.Flush()
|
|
})
|
|
}
|
|
|
|
func cmdAPGet(c *Client, args []string) error {
|
|
jsonMode, id, err := parseGetFlags("ap get", args)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var a AccessPoint
|
|
var raw []byte
|
|
if err := c.get(apiPrefix+"/access_points/"+pathID(id), &a, &raw); err != nil {
|
|
return err
|
|
}
|
|
if jsonMode {
|
|
return printJSON(raw)
|
|
}
|
|
tw := newTab()
|
|
fmt.Fprintln(tw, "ID\tNAME\tTOWER\tIP_ADDRESS")
|
|
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", a.ID, a.Name, a.Tower, a.IPAddress)
|
|
return tw.Flush()
|
|
}
|
|
|
|
func cmdAPConfig(args []string) error {
|
|
if len(args) == 0 || args[0] != "get" {
|
|
return fmt.Errorf("ap-config: expected 'get <id>'")
|
|
}
|
|
c, err := NewClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
jsonMode, id, err := parseGetFlags("ap-config get", args[1:])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var cfg AccessPointConfig
|
|
var raw []byte
|
|
if err := c.get(apiPrefix+"/access_points/"+pathID(id)+"/config", &cfg, &raw); err != nil {
|
|
return err
|
|
}
|
|
if jsonMode {
|
|
return printJSON(raw)
|
|
}
|
|
// Config is heterogeneous; pretty-print key fields and dump JSON.
|
|
tw := newTab()
|
|
if cfg.ShaperRate != nil {
|
|
fmt.Fprintf(tw, "shaper.up_speed\t%s\n", fmtSpeed(cfg.ShaperRate.UpSpeed))
|
|
fmt.Fprintf(tw, "shaper.down_speed\t%s\n", fmtSpeed(cfg.ShaperRate.DownSpeed))
|
|
fmt.Fprintf(tw, "shaper.activate\t%v\n", cfg.ShaperRate.Activate)
|
|
}
|
|
if cfg.SNMPCommunity != "" {
|
|
fmt.Fprintf(tw, "snmp_community\t%s\n", cfg.SNMPCommunity)
|
|
}
|
|
if cfg.SNMP3 != nil {
|
|
fmt.Fprintf(tw, "snmp3.security_name\t%s\n", cfg.SNMP3.SecurityName)
|
|
fmt.Fprintf(tw, "snmp3.auth_protocol\t%s\n", cfg.SNMP3.AuthProtocol)
|
|
fmt.Fprintf(tw, "snmp3.priv_protocol\t%s\n", cfg.SNMP3.PrivProtocol)
|
|
}
|
|
return tw.Flush()
|
|
}
|
|
|
|
// Score endpoints don't paginate (per spec, single response body).
|
|
func cmdAPScores(args []string) error {
|
|
fs := flag.NewFlagSet("ap-scores", flag.ExitOnError)
|
|
jsonMode := fs.Bool("json", false, "emit raw API JSON")
|
|
if err := fs.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
c, err := NewClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var raw []byte
|
|
if err := c.get(apiPrefix+"/access_point_scores", nil, &raw); err != nil {
|
|
return err
|
|
}
|
|
if *jsonMode {
|
|
return printJSON(raw)
|
|
}
|
|
// Spec is ambiguous; try array, fall back to single object.
|
|
var arr []AccessPointScore
|
|
if err := json.Unmarshal(raw, &arr); err != nil {
|
|
var one AccessPointScore
|
|
if err2 := json.Unmarshal(raw, &one); err2 == nil {
|
|
arr = []AccessPointScore{one}
|
|
} else {
|
|
return fmt.Errorf("decode ap-scores: %w (body: %s)", err, truncate(string(raw), 200))
|
|
}
|
|
}
|
|
tw := newTab()
|
|
fmt.Fprintln(tw, "NAME\tSTATUS\tSITE\tRF\tHEALTH\tCONN\tLATENCY_MS")
|
|
for _, s := range arr {
|
|
fmt.Fprintf(tw, "%s\t%s\t%s\t%.1f\t%.1f\t%d\t%.1f\n",
|
|
s.Name, s.Status, s.SiteName,
|
|
s.RFScore, s.APHealthScore, int(s.Connections), s.Latency)
|
|
}
|
|
return tw.Flush()
|
|
}
|