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