From b0a8f8d9f16321858f394bfb91204c2b6e309d8c Mon Sep 17 00:00:00 2001 From: eileencodes Date: Thu, 10 Sep 2026 10:03:00 -0400 Subject: [PATCH] Add Neki support to the CLI Neki databases can be created, connected, restored, and operated from pscale. Existing Postgres commands that apply (sql, shell, role, maintenance) accept Neki as well. New and extended commands: ``` pscale database create --engine neki pscale logs pscale size cluster list --engine neki pscale branch data-topology get|ls|update pscale branch shard list|show|create|assign|update|delete pscale branch config-profile list|show|create|update|delete pscale branch config-profile default|set-default|parameters|maintenance pscale branch config-profile extensions|extensions enable|extensions disable pscale branch config-profile changes list|show|cancel pscale branch router list|show|create|update|delete|sizes pscale branch router changes list|show|cancel pscale branch sidecar list|show|update|parameters pscale branch sidecar changes list|show|cancel pscale branch admin show|update|parameters|sizes pscale branch admin changes list|show|cancel pscale branch maintenance run pscale backup restore pscale backup restore show ``` Neki restore accepts --config-profile and --router; --cluster-size is optional so the source default profile size is kept. Shell accepts --router for Neki routing. --- AGENTS.md | 256 +++++++- internal/cmd/admin/admin.go | 234 +++++++ internal/cmd/admin/admin_test.go | 364 +++++++++++ internal/cmd/admin/changes.go | 154 +++++ internal/cmd/admin/errors.go | 18 + internal/cmd/admin/parameters.go | 49 ++ internal/cmd/admin/show.go | 64 ++ internal/cmd/admin/sizes.go | 82 +++ internal/cmd/admin/update.go | 97 +++ internal/cmd/backup/backup.go | 2 +- internal/cmd/backup/restore.go | 34 +- internal/cmd/backup/restore_show.go | 177 ++++++ internal/cmd/backup/restore_show_test.go | 183 ++++++ internal/cmd/backup/restore_test.go | 143 +++++ internal/cmd/branch/branch.go | 85 ++- internal/cmd/branch/branch_test.go | 45 ++ internal/cmd/branch/connections.go | 11 +- .../cmd/branch/connections/engine_flags.go | 5 + .../branch/connections/engine_flags_test.go | 16 + internal/cmd/branch/connections/top.go | 2 +- internal/cmd/branch/connections/top_test.go | 6 + internal/cmd/branch/connections_commands.go | 3 + internal/cmd/branch/connections_test.go | 41 ++ internal/cmd/branch/create.go | 38 +- internal/cmd/branch/create_test.go | 265 ++++++++ internal/cmd/branch/data_topology.go | 208 ++++++ internal/cmd/branch/data_topology_output.go | 36 ++ internal/cmd/branch/data_topology_shards.go | 79 +++ internal/cmd/branch/data_topology_test.go | 426 +++++++++++++ internal/cmd/branch/data_topology_tree.go | 593 ++++++++++++++++++ internal/cmd/branch/diff.go | 2 +- internal/cmd/branch/lint.go | 2 +- internal/cmd/branch/maintenance.go | 21 +- internal/cmd/branch/maintenance_test.go | 157 ++--- internal/cmd/branch/query_patterns.go | 4 +- internal/cmd/branch/refresh_schema.go | 2 +- internal/cmd/branch/routing_rules.go | 6 +- internal/cmd/branch/safe_migrations.go | 6 +- internal/cmd/configprofile/changes.go | 158 +++++ internal/cmd/configprofile/config_profile.go | 366 +++++++++++ .../cmd/configprofile/config_profile_test.go | 465 ++++++++++++++ internal/cmd/configprofile/create.go | 64 ++ internal/cmd/configprofile/default.go | 38 ++ internal/cmd/configprofile/delete.go | 62 ++ internal/cmd/configprofile/errors.go | 19 + internal/cmd/configprofile/extensions.go | 95 +++ internal/cmd/configprofile/list.go | 44 ++ internal/cmd/configprofile/maintenance.go | 80 +++ internal/cmd/configprofile/parameters.go | 74 +++ internal/cmd/configprofile/set_default.go | 44 ++ internal/cmd/configprofile/show.go | 40 ++ internal/cmd/configprofile/update.go | 100 +++ internal/cmd/database/create.go | 47 +- internal/cmd/database/create_test.go | 72 ++- internal/cmd/keyspace/keyspace.go | 2 - internal/cmd/keyspace/settings.go | 8 - internal/cmd/keyspace/update_settings.go | 40 +- internal/cmd/keyspace/update_settings_test.go | 241 ------- internal/cmd/logs/logs.go | 327 ++++++++++ internal/cmd/logs/logs_test.go | 287 +++++++++ internal/cmd/role/create.go | 4 +- internal/cmd/role/get.go | 13 +- internal/cmd/role/list.go | 47 +- internal/cmd/role/output_test.go | 302 +++++++++ internal/cmd/role/renew.go | 2 +- internal/cmd/role/reset.go | 2 +- internal/cmd/role/reset_default.go | 45 +- internal/cmd/role/role.go | 4 +- internal/cmd/role/update.go | 2 +- internal/cmd/root.go | 21 +- internal/cmd/root_test.go | 11 + internal/cmd/router/changes.go | 158 +++++ internal/cmd/router/create.go | 60 ++ internal/cmd/router/delete.go | 63 ++ internal/cmd/router/errors.go | 23 + internal/cmd/router/list.go | 48 ++ internal/cmd/router/router.go | 319 ++++++++++ internal/cmd/router/router_test.go | 471 ++++++++++++++ internal/cmd/router/show.go | 65 ++ internal/cmd/router/sizes.go | 90 +++ internal/cmd/router/update.go | 124 ++++ internal/cmd/shard/assign.go | 51 ++ internal/cmd/shard/create.go | 60 ++ internal/cmd/shard/delete.go | 63 ++ internal/cmd/shard/errors.go | 28 + internal/cmd/shard/list.go | 68 ++ internal/cmd/shard/shard.go | 130 ++++ internal/cmd/shard/shard_test.go | 287 +++++++++ internal/cmd/shard/show.go | 44 ++ internal/cmd/shard/update.go | 61 ++ internal/cmd/shell/shell.go | 63 +- internal/cmd/shell/shell_test.go | 38 ++ internal/cmd/sidecar/changes.go | 158 +++++ internal/cmd/sidecar/errors.go | 23 + internal/cmd/sidecar/list.go | 48 ++ internal/cmd/sidecar/parameters.go | 50 ++ internal/cmd/sidecar/show.go | 66 ++ internal/cmd/sidecar/sidecar.go | 217 +++++++ internal/cmd/sidecar/sidecar_test.go | 323 ++++++++++ internal/cmd/sidecar/update.go | 84 +++ internal/cmd/size/cluster.go | 90 +-- internal/cmd/size/cluster_test.go | 59 +- internal/cmd/sql/sql.go | 4 +- internal/cmdutil/args_test.go | 25 + internal/cmdutil/cmdutil.go | 183 ++++++ internal/cmdutil/json_error.go | 5 +- internal/cmdutil/json_error_test.go | 10 + internal/cmdutil/neki_restore_test.go | 82 +++ internal/cmdutil/postgres.go | 23 + internal/mock/branch.go | 16 + internal/mock/neki_admins.go | 65 ++ internal/mock/neki_routers.go | 89 +++ .../mock/neki_shard_configuration_profiles.go | 92 +++ internal/mock/neki_shards.go | 57 ++ internal/mock/neki_sidecars.go | 65 ++ internal/planetscale/branches.go | 2 + internal/planetscale/client.go | 106 ++-- internal/planetscale/data_topology.go | 62 ++ internal/planetscale/data_topology_test.go | 85 +++ internal/planetscale/databases.go | 1 + internal/planetscale/keyspaces.go | 17 - internal/planetscale/keyspaces_test.go | 43 -- internal/planetscale/logs.go | 108 ++++ internal/planetscale/logs_test.go | 107 ++++ internal/planetscale/neki_admins.go | 204 ++++++ internal/planetscale/neki_admins_test.go | 118 ++++ internal/planetscale/neki_routers.go | 300 +++++++++ internal/planetscale/neki_routers_test.go | 269 ++++++++ .../neki_shard_configuration_profiles.go | 411 ++++++++++++ .../neki_shard_configuration_profiles_test.go | 241 +++++++ internal/planetscale/neki_shards.go | 214 +++++++ internal/planetscale/neki_shards_test.go | 138 ++++ internal/planetscale/neki_sidecars.go | 202 ++++++ internal/planetscale/neki_sidecars_test.go | 111 ++++ internal/planetscale/postgres_branches.go | 20 + .../planetscale/postgres_branches_test.go | 66 ++ internal/planetscale/postgres_roles.go | 4 +- internal/planetscale/postgres_roles_test.go | 60 ++ internal/roleutil/roleutil.go | 55 ++ internal/roleutil/roleutil_test.go | 106 ++++ internal/sqlquery/session.go | 4 +- internal/sqlquery/sqlquery.go | 12 +- internal/sqlquery/sqlquery_test.go | 63 ++ 143 files changed, 13654 insertions(+), 665 deletions(-) create mode 100644 internal/cmd/admin/admin.go create mode 100644 internal/cmd/admin/admin_test.go create mode 100644 internal/cmd/admin/changes.go create mode 100644 internal/cmd/admin/errors.go create mode 100644 internal/cmd/admin/parameters.go create mode 100644 internal/cmd/admin/show.go create mode 100644 internal/cmd/admin/sizes.go create mode 100644 internal/cmd/admin/update.go create mode 100644 internal/cmd/backup/restore_show.go create mode 100644 internal/cmd/backup/restore_show_test.go create mode 100644 internal/cmd/branch/branch_test.go create mode 100644 internal/cmd/branch/connections/engine_flags_test.go create mode 100644 internal/cmd/branch/data_topology.go create mode 100644 internal/cmd/branch/data_topology_output.go create mode 100644 internal/cmd/branch/data_topology_shards.go create mode 100644 internal/cmd/branch/data_topology_test.go create mode 100644 internal/cmd/branch/data_topology_tree.go create mode 100644 internal/cmd/configprofile/changes.go create mode 100644 internal/cmd/configprofile/config_profile.go create mode 100644 internal/cmd/configprofile/config_profile_test.go create mode 100644 internal/cmd/configprofile/create.go create mode 100644 internal/cmd/configprofile/default.go create mode 100644 internal/cmd/configprofile/delete.go create mode 100644 internal/cmd/configprofile/errors.go create mode 100644 internal/cmd/configprofile/extensions.go create mode 100644 internal/cmd/configprofile/list.go create mode 100644 internal/cmd/configprofile/maintenance.go create mode 100644 internal/cmd/configprofile/parameters.go create mode 100644 internal/cmd/configprofile/set_default.go create mode 100644 internal/cmd/configprofile/show.go create mode 100644 internal/cmd/configprofile/update.go create mode 100644 internal/cmd/logs/logs.go create mode 100644 internal/cmd/logs/logs_test.go create mode 100644 internal/cmd/role/output_test.go create mode 100644 internal/cmd/router/changes.go create mode 100644 internal/cmd/router/create.go create mode 100644 internal/cmd/router/delete.go create mode 100644 internal/cmd/router/errors.go create mode 100644 internal/cmd/router/list.go create mode 100644 internal/cmd/router/router.go create mode 100644 internal/cmd/router/router_test.go create mode 100644 internal/cmd/router/show.go create mode 100644 internal/cmd/router/sizes.go create mode 100644 internal/cmd/router/update.go create mode 100644 internal/cmd/shard/assign.go create mode 100644 internal/cmd/shard/create.go create mode 100644 internal/cmd/shard/delete.go create mode 100644 internal/cmd/shard/errors.go create mode 100644 internal/cmd/shard/list.go create mode 100644 internal/cmd/shard/shard.go create mode 100644 internal/cmd/shard/shard_test.go create mode 100644 internal/cmd/shard/show.go create mode 100644 internal/cmd/shard/update.go create mode 100644 internal/cmd/sidecar/changes.go create mode 100644 internal/cmd/sidecar/errors.go create mode 100644 internal/cmd/sidecar/list.go create mode 100644 internal/cmd/sidecar/parameters.go create mode 100644 internal/cmd/sidecar/show.go create mode 100644 internal/cmd/sidecar/sidecar.go create mode 100644 internal/cmd/sidecar/sidecar_test.go create mode 100644 internal/cmd/sidecar/update.go create mode 100644 internal/cmdutil/args_test.go create mode 100644 internal/cmdutil/neki_restore_test.go create mode 100644 internal/mock/neki_admins.go create mode 100644 internal/mock/neki_routers.go create mode 100644 internal/mock/neki_shard_configuration_profiles.go create mode 100644 internal/mock/neki_shards.go create mode 100644 internal/mock/neki_sidecars.go create mode 100644 internal/planetscale/data_topology.go create mode 100644 internal/planetscale/data_topology_test.go create mode 100644 internal/planetscale/logs.go create mode 100644 internal/planetscale/logs_test.go create mode 100644 internal/planetscale/neki_admins.go create mode 100644 internal/planetscale/neki_admins_test.go create mode 100644 internal/planetscale/neki_routers.go create mode 100644 internal/planetscale/neki_routers_test.go create mode 100644 internal/planetscale/neki_shard_configuration_profiles.go create mode 100644 internal/planetscale/neki_shard_configuration_profiles_test.go create mode 100644 internal/planetscale/neki_shards.go create mode 100644 internal/planetscale/neki_shards_test.go create mode 100644 internal/planetscale/neki_sidecars.go create mode 100644 internal/planetscale/neki_sidecars_test.go create mode 100644 internal/roleutil/roleutil_test.go diff --git a/AGENTS.md b/AGENTS.md index 214f5419b..cf5e825b3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -240,7 +240,7 @@ pscale sql --org --format json --query "SELECT 1" # Read from replica pscale sql --org --format json --replica --query "SELECT 1" -# PostgreSQL — optional --dbname (default postgres) +# Postgres or Neki — optional --dbname (default postgres) pscale sql --org --format json --query "SELECT 1" # MySQL multi-keyspace — optional --keyspace (default @primary) @@ -251,11 +251,11 @@ pscale sql --org --format json --keyspace - |------|---------| | `--role` | `reader` (default), `writer`, `readwriter`, `admin` — same names as `pscale shell` | | `--replica` | Route reads to replicas | -| `--dbname` | PostgreSQL database name (default `postgres`) | +| `--dbname` | Postgres or Neki database name (default `postgres`) | | `--keyspace` | MySQL keyspace (default `@primary`); may include a shard and tablet type: `mykeyspace/-80`, `mykeyspace/-80@replica` | | `--force` | Allow destructive SQL after explicit user approval | -**`--role` by engine** (same as `pscale shell`): +**`--role` by engine** (same as `pscale shell`; Neki uses the Postgres behavior): | `--role` | MySQL (Vitess) | PostgreSQL | |----------|----------------|------------| @@ -287,6 +287,41 @@ Error: one JSON object on stdout with `status: "error"`, `error`, `issues`, and Destructive SQL without `--force`: `status: "action_required"`, `query_kind: "destructive"`, `issues`, and `next_steps` (includes `--force` retry command). +## Branch logs + +`pscale logs` queries recent logs for a PostgreSQL or Neki branch. It obtains a signed logs URL from the API and prints parsed entries; API credentials are not sent to the signed logs host. + +```bash +# Last hour from the primary server (default) +pscale logs --org --format json + +# Search errors across the last six hours +pscale logs --org --format json --period 6h --level ERROR --query "connection refused" + +# Query an exact ISO 8601 time range +pscale logs --org --format json --from --to + +# Query selected Neki shards and pods +pscale logs --org --format json --shard --server + +# Fetch the next page (100 entries per page by default) +pscale logs --org --format json --page 2 +``` + +| Flag | Purpose | +|------|---------| +| `--query` | Text or LogsQL expression; pipeline stages after `\|` are preserved | +| `--period` | `15m`, `1h` (default), `3h`, `6h`, `12h`, `1d`, `7d`, or `8d` | +| `--from` | Start of a custom ISO 8601 time range; must be used with `--to` and cannot be combined with `--period` | +| `--to` | End of a custom ISO 8601 time range; must be used with `--from` and cannot be combined with `--period` | +| `--level` | Comma-separated or repeatable `DEBUG`, `INFO`, `WARNING`, or `ERROR` filters | +| `--server` | Comma-separated or repeatable server filters; `primary` (default) selects the primary role, other values select pod names | +| `--shard` | Comma-separated or repeatable Neki shard filters | +| `--limit` | Maximum entries per page (default `100`) | +| `--page` | Page number; translated to a LogsQL offset (default `1`) | + +Human output prints one event per line as `