package cli import ( "context" "flag" "fmt" "strings" "github.com/peterbourgon/ff/v3/ffcli" "edge-infra.dev/pkg/lib/gcp/monitoring/metrics" "edge-infra.dev/pkg/lib/gcp/monitoring/monutil" ) type deleteArgsT struct { labels string noPrompt bool } var filterLabels []string var deleteArgs deleteArgsT var deleteFlagSet = newDeleteFlagSet(&deleteArgs) func newDeleteFlagSet(deleteArgs *deleteArgsT) *flag.FlagSet { deletef := newFlagSet("delete") deletef.BoolVar(&deleteArgs.noPrompt, "no-prompt", false, "Determines whether the user will be prompted to confirm each deletion.") deletef.StringVar(&deleteArgs.labels, "with-labels", "", "Comma separated list of labels to filter the list of metric descriptors to delete. Only metric descriptors that contain this label will be deleted.") return deletef } var deleteCmd = &ffcli.Command{ Name: "delete", ShortUsage: "delete [flags]", ShortHelp: "Used to delete metric descriptors.", LongHelp: strings.TrimSpace(` Deletes one or more metric descriptors from one or more projects, with an optional label filter. `), FlagSet: withGlobalFlags(deleteFlagSet), Exec: runDelete, } func runDelete(ctx context.Context, args []string) error { var err error if len(args) > 0 { Fatalf("too many non-flag arguments: %q", args) } if !checkDeleteFlags() { _, _ = Println() return flag.ErrHelp } // retrieve list of metric descriptors for all projectIDs specified projects := strings.Split(strings.ReplaceAll(projectID, " ", ""), ",") d, err := retrieveDescriptors(ctx, projects) if err != nil { return Errorf("failed to metricDescriptors for multiple projects: %w", err) } // necessary when specifying multiple projects as foreman is a multi-project source if filterForeman { projects := strings.Split(strings.ReplaceAll(projectID, " ", ""), ",") d, err = d.FilterProjects(projects) if err != nil { return err } } // filter by labels if len(deleteArgs.labels) != 0 { filterLabels = strings.Split(strings.ReplaceAll(deleteArgs.labels, " ", ""), ",") d, err = d.FilterLabels(filterLabels) if err != nil { return err } } // parse through descriptors list to delete var dR metrics.DeleteReport for i := 0; i < len(d.Descriptor); i++ { var err error var confirmed = false if !deleteArgs.noPrompt && !silent { monutil.ClearTerminal() _ = metrics.TmplDesc.Execute(Stdout, d.Descriptor[i]) confirmed = monutil.PromptYesNoCancel("Do you wish to delete this metric descriptor?") } if confirmed || silent || deleteArgs.noPrompt { dR.Attempted++ err = deleteDescriptor(ctx, &d.Descriptor[i]) } else { dR.Skipped = append(dR.Skipped, d.Descriptor[i].Name) continue } if err != nil { dR.Failed = append(dR.Failed, d.Descriptor[i].Name) } else { dR.Completed++ dR.Deleted = append(dR.Deleted, d.Descriptor[i].Name) } } if silent { // output report to json _ = metrics.TmplJSON.Execute(Stdout, dR) } else { // output visual layout of align report monutil.ClearTerminal() _ = metrics.TmplDeleteReport.Execute(Stdout, dR) fmt.Printf("\n\n%s", monutil.White(mmBroomTitle)) } return nil } // checkGetFlags validates the required get subcommand flags have been provided. func checkDeleteFlags() bool { return true } // create client and delete request func deleteDescriptor(ctx context.Context, d *metrics.Descriptor) error { pID := metrics.ParseProjectID(d.Name) mName := metrics.ParseMetricName(d.Name) prefix := metrics.ParsePrefix(d.Name) dClient, err := metrics.New(ctx, pID) if err != nil { return err } return dClient.DeleteDescriptor(prefix, mName) }