network/preseem/cmd_clear.go
2026-07-19 14:42:02 -05:00

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
}