package cli import ( "context" "flag" "fmt" "strings" "github.com/peterbourgon/ff/v3/ffcli" metrics "edge-infra.dev/pkg/lib/gcp/monitoring/metrics" "edge-infra.dev/pkg/lib/gcp/monitoring/monutil" ) type listArgsT struct { byProject bool byMetric bool labels string } var ( listArgs listArgsT listFlagSet = newListFlagSet(&listArgs) ) func newListFlagSet(listArgs *listArgsT) *flag.FlagSet { listf := newFlagSet("list") listf.BoolVar(&listArgs.byProject, "by-project", false, "Lists metric descriptors sorted by project ID. (cannot be used with --by-metric or --by-label)") listf.BoolVar(&listArgs.byMetric, "by-metric", false, "Lists metric descriptors sorted by metric. (cannot be used with --by-project or --by-label)") return listf } var listCmd = &ffcli.Command{ Name: "list", ShortUsage: "list [flags]", ShortHelp: "list metric descriptors from a project", LongHelp: strings.TrimSpace(` Lists metric descriptors for one or more projects that match the specified metric type. `), FlagSet: withGlobalFlags(listFlagSet), Exec: runList, } func runList(ctx context.Context, args []string) error { var err error if len(args) > 0 { Fatalf("too many non-flag arguments: %q", args) } if !checkListFlags() || !checkGlobalFlags() { return flag.ErrHelp } projects := strings.Split(strings.ReplaceAll(projectID, " ", ""), ",") d, err := retrieveDescriptors(ctx, projects) if err != nil { return Errorf("failed to get retrieve of metricDescriptors: %w", err) } // necessary when comparing specific projects as foreman is a multi-project source if filterForeman { projects := strings.Split(strings.ReplaceAll(projectID, " ", ""), ",") f, err := d.FilterProjects(projects) if err != nil { return err } d = f } if len(d.Descriptor) == 0 && !silent { fmt.Println(monutil.White("No metric descriptors found for the specified project(s) as specified.")) } // output the list to the appropriate template switch { case listArgs.byMetric && !jsonFormat: _ = metrics.TmplMetricList.Execute(Stdout, d.ListMetrics()) case listArgs.byProject && !jsonFormat: _ = metrics.TmplProjectList.Execute(Stdout, d.ListProjects()) case listArgs.byMetric && jsonFormat: _ = metrics.TmplJSON.Execute(Stdout, d.ListMetrics()) case listArgs.byProject && jsonFormat: _ = metrics.TmplJSON.Execute(Stdout, d.ListProjects()) case !listArgs.byMetric && !listArgs.byProject && jsonFormat: _ = metrics.TmplJSON.Execute(Stdout, d) default: _ = metrics.TmplDescList.Execute(Stdout, d) } return nil } // checkListFlags validates the required List subcommand flags have been provided. func checkListFlags() bool { // filter descriptors for those that contain the specified label(s) if len(listArgs.labels) != 0 { // filterLabels = true // labelFilter = strings.Split(listArgs.labels, ",") // TBD - remove stop error once label support is complete fmt.Println("Error: 'with-label' not supported yet - coming soon") return false } if listArgs.byMetric && listArgs.byProject { fmt.Println("Error: 'by-metric' and 'by-project' were selected - only one sort method allowed") return false } return true }