blob: bfbb21d6e019ca010f90bcd7bab81c67460402a7 [file] [log] [blame]
Tim Windelschmidtde12c7e2024-04-25 18:00:40 +02001package main
2
3import (
4 "context"
5 "fmt"
6 "os"
7 "os/signal"
8 "slices"
9 "strings"
10
11 "github.com/packethost/packngo"
12 "github.com/spf13/cobra"
13 "k8s.io/klog/v2"
14
15 "source.monogon.dev/cloud/equinix/wrapngo"
16)
17
18var listCmd = &cobra.Command{
19 Use: "list",
20 Long: `This lists all hardware reservations inside a specified organization or project.`,
21 Args: cobra.NoArgs,
22 Run: doList,
23}
24
25func init() {
26 listCmd.Flags().String("equinix_organization", "", "from which organization to list from")
27 listCmd.Flags().String("equinix_project", "", "from which project to list from")
28 rootCmd.AddCommand(listCmd)
29}
30
31func doList(cmd *cobra.Command, args []string) {
32 organization, err := cmd.Flags().GetString("equinix_organization")
33 if err != nil {
34 klog.Exitf("flag: %v", err)
35 }
36
37 project, err := cmd.Flags().GetString("equinix_project")
38 if err != nil {
39 klog.Exitf("flag: %v", err)
40 }
41
42 if organization == "" && project == "" {
43 klog.Exitf("missing organization or project flag")
44 }
45
46 ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
47 api := wrapngo.New(&c)
48
49 var (
50 reservations []packngo.HardwareReservation
51 )
52 switch {
53 case project != "" && organization == "":
54 klog.Infof("Listing reservations for project: %s", project)
55 reservations, err = api.ListReservations(ctx, project)
56 case organization != "" && project == "":
57 klog.Infof("Listing reservations for organization: %s", organization)
58 reservations, err = api.ListOrganizationReservations(ctx, organization)
59 default:
60 klog.Exitf("exactly one of organization or project flags has to be set")
61 }
62
63 if err != nil {
64 klog.Fatalf("Failed to list reservations: %v", err)
65 }
66
67 type configDC struct {
68 config string
69 dc string
70 }
71 type configDCP struct {
72 configDC
73 project string
74 }
75 mtypes := make(map[configDC]int)
76 mptypes := make(map[configDCP]int)
77
78 klog.Infof("Got %d reservations", len(reservations))
79 for _, r := range reservations {
80 curType := configDC{config: strings.ToLower(r.Plan.Name), dc: strings.ToLower(r.Facility.Metro.Code)}
81 curPType := configDCP{curType, r.Project.Name}
82 mtypes[curType]++
83 mptypes[curPType]++
84 }
85
86 klog.Infof("Found the following configurations:")
87 var mStrings []string
88 for dc, c := range mtypes {
89 mStrings = append(mStrings, fmt.Sprintf("%s | %s | %d", dc.dc, dc.config, c))
90 }
91 slices.Sort(mStrings)
92 for _, s := range mStrings {
93 klog.Info(s)
94 }
95
96 klog.Infof("Found the following configurations (per project):")
97 var mpStrings []string
98 for dc, c := range mptypes {
99 mpStrings = append(mpStrings, fmt.Sprintf("%s | %s | %s | %d", dc.project, dc.dc, dc.config, c))
100 }
101 slices.Sort(mpStrings)
102 for _, s := range mpStrings {
103 klog.Info(s)
104 }
105}