feat(BA-4668): Add CLI commands for prometheus query preset admin CRUD and execution#9641
feat(BA-4668): Add CLI commands for prometheus query preset admin CRUD and execution#9641seedspirit wants to merge 2 commits intomainfrom
Conversation
…D and execution - Add SDK function class (client/func/prometheus_query_preset.py) with create, list_presets, get, modify, delete, and execute methods - Add admin CLI commands (list, info, add, modify, delete) under `backend.ai admin prometheus-query-preset` - Add top-level execute CLI command under `backend.ai prometheus-query-preset execute` with repeatable --label flag - Register SDK function in BaseSession and CLI groups in __init__ modules Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds a new Prometheus query preset feature across the client SDK and CLI, enabling superadmins to CRUD presets and all authenticated users to execute them.
Changes:
- Added
PrometheusQueryPresetclient SDK function with CRUD + execute methods. - Added admin CLI commands for preset CRUD (
backend.ai admin prometheus-query-preset ...). - Added a top-level CLI command for executing presets with repeatable
--label key=value.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ai/backend/client/session.py | Registers PrometheusQueryPreset as a session function. |
| src/ai/backend/client/func/prometheus_query_preset.py | Implements REST-backed SDK methods for CRUD and execution. |
| src/ai/backend/client/cli/prometheus_query_preset/commands.py | Adds execute CLI command and argument parsing. |
| src/ai/backend/client/cli/prometheus_query_preset/init.py | Declares the top-level Click command group. |
| src/ai/backend/client/cli/admin/prometheus_query_preset.py | Adds admin CRUD Click commands. |
| src/ai/backend/client/cli/admin/init.py | Wires the new admin command group into the admin CLI. |
| src/ai/backend/client/cli/init.py | Wires the new top-level command group into the CLI entrypoint. |
| changes/9641.feature.md | Adds changelog entry for the new CLI feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| @prometheus_query_preset.command() | ||
| @pass_ctx_obj | ||
| def list(ctx: CLIContext) -> None: |
There was a problem hiding this comment.
def list(...) shadows the Python built-in list, and this repo appears to enforce built-in name checks (e.g., # noqa: A004 for license). Consider renaming the function (e.g., list_ / list_cmd) while keeping the CLI command name via @prometheus_query_preset.command(name=\"list\").
| @prometheus_query_preset.command() | |
| @pass_ctx_obj | |
| def list(ctx: CLIContext) -> None: | |
| @prometheus_query_preset.command(name="list") | |
| @pass_ctx_obj | |
| def list_cmd(ctx: CLIContext) -> None: |
| @prometheus_query_preset.command() | ||
| @pass_ctx_obj | ||
| @click.argument("preset_id", type=str) | ||
| @click.option("--name", type=str, default=None, help="New preset name.") | ||
| @click.option("--metric-name", type=str, default=None, help="New Prometheus metric name.") | ||
| @click.option("--query-template", type=str, default=None, help="New PromQL template.") | ||
| @click.option("--time-window", type=str, default=None, help="New default time window.") | ||
| @click.option( | ||
| "--options", | ||
| type=JSONParamType(), | ||
| default=None, | ||
| help="New preset options JSON.", | ||
| ) |
There was a problem hiding this comment.
The modify command allows invoking the API with no fields provided (all options default to None), which will send an empty PATCH body and likely fail server-side. Add a client-side validation before calling modify to require at least one of name/metric_name/query_template/time_window/options to be set; otherwise exit with ExitCode.INVALID_ARGUMENT (or raise a Click parameter error).
| result = session.PrometheusQueryPreset.modify( | ||
| UUID(preset_id), | ||
| name=name, | ||
| metric_name=metric_name, | ||
| query_template=query_template, | ||
| time_window=time_window, | ||
| options=options, | ||
| ) |
There was a problem hiding this comment.
The modify command allows invoking the API with no fields provided (all options default to None), which will send an empty PATCH body and likely fail server-side. Add a client-side validation before calling modify to require at least one of name/metric_name/query_template/time_window/options to be set; otherwise exit with ExitCode.INVALID_ARGUMENT (or raise a Click parameter error).
| if "=" not in label: | ||
| print(f"Invalid label format: {label} (expected key=value)", file=sys.stderr) | ||
| sys.exit(ExitCode.INVALID_ARGUMENT) | ||
| key, value = label.split("=", 1) |
There was a problem hiding this comment.
This accepts --label values like =foo or bar= and will send empty keys/values to the API. Validate that both key and value are non-empty (and consider stripping whitespace) before appending; if invalid, fail with ExitCode.INVALID_ARGUMENT (or raise click.BadParameter).
| key, value = label.split("=", 1) | |
| key, value = label.split("=", 1) | |
| key = key.strip() | |
| value = value.strip() | |
| if not key or not value: | |
| print( | |
| f"Invalid label key or value: {label} (both key and value must be non-empty)", | |
| file=sys.stderr, | |
| ) | |
| sys.exit(ExitCode.INVALID_ARGUMENT) |
Summary
PrometheusQueryPreset) with create, list, get, modify, delete, and execute methods calling the REST API endpoints defined in BEP-1050backend.ai admin prometheus-query-preset list|info|add|modify|delete) for superadmin CRUD operationsbackend.ai prometheus-query-preset execute) with repeatable--label key=valueflag for all authenticated usersTest plan
backend.ai admin prometheus-query-preset listreturns presetsbackend.ai admin prometheus-query-preset add --name test --metric-name m --query-template qcreates a presetbackend.ai admin prometheus-query-preset info <ID>shows preset detailsbackend.ai admin prometheus-query-preset modify <ID> --name new_nameupdates a presetbackend.ai admin prometheus-query-preset delete <ID>deletes a preset with confirmationbackend.ai prometheus-query-preset execute <ID> --start ... --end ... --step ...sends proper API request--labelflag supports repeatable key=value formatResolves BA-4668