107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
)
|
|
|
|
func cmdClearServices(args []string) error {
|
|
fs := flag.NewFlagSet("clear-services", flag.ExitOnError)
|
|
dryRun := fs.Bool("dry-run", false, "list what would be deleted without deleting")
|
|
confirm := fs.Bool("confirm", false, "actually delete (required)")
|
|
accountFilter := fs.String("account", "", "only clear services for this account ID")
|
|
if err := fs.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !*dryRun && !*confirm {
|
|
return fmt.Errorf("clear-services requires --confirm to actually delete, or --dry-run to preview")
|
|
}
|
|
|
|
c, err := NewClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Fetch all services.
|
|
items, _, err := c.listAll("/services", 1000, decodeListPage)
|
|
if err != nil {
|
|
return fmt.Errorf("list services: %w", err)
|
|
}
|
|
|
|
// Filter by account if requested.
|
|
var toDelete []Service
|
|
for _, rm := range items {
|
|
var s Service
|
|
if err := json.Unmarshal(rm, &s); err != nil {
|
|
log.Printf("skip unparseable service: %v", err)
|
|
continue
|
|
}
|
|
if *accountFilter != "" && s.Account != *accountFilter {
|
|
continue
|
|
}
|
|
toDelete = append(toDelete, s)
|
|
}
|
|
|
|
if len(toDelete) == 0 {
|
|
fmt.Println("no services to delete")
|
|
return nil
|
|
}
|
|
|
|
fmt.Printf("%d services to delete", len(toDelete))
|
|
if *accountFilter != "" {
|
|
fmt.Printf(" for account %q", *accountFilter)
|
|
}
|
|
fmt.Println()
|
|
|
|
if *dryRun {
|
|
for _, s := range toDelete {
|
|
macs := attachmentMACs(s)
|
|
fmt.Printf(" %s account=%s macs=%s up=%d down=%d\n",
|
|
s.ID, s.Account, strings.Join(macs, ","), s.UpSpeed, s.DownSpeed)
|
|
}
|
|
fmt.Println("--dry-run: no services were deleted")
|
|
return nil
|
|
}
|
|
|
|
// Actually delete.
|
|
var deleted, failed int
|
|
for _, s := range toDelete {
|
|
path := apiPrefix + "/services/" + pathID(s.ID)
|
|
if err := c.del(path); err != nil {
|
|
log.Printf("FAIL %s: %v", s.ID, err)
|
|
failed++
|
|
} else {
|
|
macs := attachmentMACs(s)
|
|
fmt.Printf("deleted %s account=%s macs=%s\n", s.ID, s.Account, strings.Join(macs, ","))
|
|
deleted++
|
|
}
|
|
}
|
|
|
|
fmt.Printf("\n%d deleted, %d failed\n", deleted, failed)
|
|
if failed > 0 {
|
|
return fmt.Errorf("%d deletions failed", failed)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func attachmentMACs(s Service) []string {
|
|
var macs []string
|
|
for _, a := range s.Attachments {
|
|
if a.CPEMac != "" {
|
|
macs = append(macs, a.CPEMac)
|
|
} else if a.CPESerial != "" {
|
|
macs = append(macs, "sn:"+a.CPESerial)
|
|
} else if a.CPEIMSI != "" {
|
|
macs = append(macs, "imsi:"+a.CPEIMSI)
|
|
} else if a.Username != "" {
|
|
macs = append(macs, "u:"+a.Username)
|
|
} else if len(a.NetworkPrefixes) > 0 {
|
|
macs = append(macs, "pfx:"+a.NetworkPrefixes[0])
|
|
}
|
|
}
|
|
return macs
|
|
}
|