Skip to content

Expose new API fields in CLI (#289)#301

Open
sdairs wants to merge 5 commits into
mainfrom
issue-289-cli-exposure
Open

Expose new API fields in CLI (#289)#301
sdairs wants to merge 5 commits into
mainfrom
issue-289-cli-exposure

Conversation

@sdairs

@sdairs sdairs commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Exposes the four groups of API surface landed in the OpenAPI drift fixes (#298 / #299 / #300) as user-facing CLI commands, per the plan in #289.

Closes #289.

Changes

1. ClickPipe object-storage ingestion control

  • --skip-initial-load: skip the initial snapshot load, only ingest new objects (continuous/SQS pipes only; requires --queue-url).
  • --start-after: resume ingestion after a specific object key (conflicts with --skip-initial-load).
  • Serialize to skipInitialLoad / startAfter on the object-storage source body.

2. Service horizontal autoscaling (service create / service scale)

  • --min-replicas / --max-replicas / --autoscaling-mode.
  • The horizontal pair is mutually exclusive with the vertical flags (--num-replicas / --min-replica-memory-gb / --max-replica-memory-gb) via clap conflicts_with_all.
  • The mode is sent only when --autoscaling-mode is given explicitly; the API resolves an omitted mode itself (an equal --min-replicas/--max-replicas band with the mode omitted is a vertical fixed replica count needing no horizontal entitlement, so the CLI must not infer horizontal).
  • Rejects --min-replicas without --max-replicas (and vice versa) with a clear error before any network call.
  • Shared resolution logic extracted into resolve_horizontal_autoscalingHorizontalAutoscaling struct (used by both create and scale via build_create_service_request / build_service_scale_request).

3. ClickPipe MySQL --server-id

  • Sets the replication server ID (useful when multiple pipes read from the same MySQL instance). Serializes to serverId on the MySQL source body.

4. ClickPipe schema discovery (beta)

  • New clickpipe schema-discover <SERVICE_ID> <kafka|kinesis> command.
  • POSTs to /clickpipes/schemaDiscovery and renders the inferred fields (table by default, JSON with --json / agent detection).
  • Source connection flags are shared with the create subcommands via KafkaSourceFields / KinesisSourceFields #[command(flatten)] structs — no service_id positional clash, no destination (--name/--database/--table/--column) flags needed.
  • Classified as a write command (requires API key auth; OAuth/bearer is rejected).

API library

  • Adds AutoscalingMode::VALUES const (drift-guarded by the analyzer's existing enum-values check).
  • Adds click_pipe_schema_discovery wrapper on CloudClient.

Tests

  • Bin (394 pass): build_create_service_request / build_service_scale_request unit tests (minimal + maximal) for horizontal autoscaling; resolve_horizontal_autoscaling edge cases (explicit vertical with no replicas, min-without-max rejection, invalid mode); Cli::try_parse_from coverage for all new flags (object-storage ingestion, MySQL server-id, autoscaling on create/scale, schema-discover kafka/kinesis).
  • Wiremock (50 pass): object-storage skipInitialLoad/startAfter on the wire (present + absent); MySQL serverId (present + absent); schema-discovery POST body shape for kafka + kinesis.
  • API library + analyzer: all pass; cargo clippy -p clickhouse-cloud-api -p clickhouse-openapi-analyzer --all-targets -- -D warnings clean.
  • Drift: python3 scripts/check-openapi-drift.py --dry-run → 0 actionable drift.
  • All-features: cargo check --workspace --all-features clean.

Docs

  • README updated: horizontal autoscaling table rows + service create/scale examples; object-storage continuous ingestion example with --skip-initial-load/--start-after; MySQL --server-id example; new "Discovering a source schema (beta)" subsection under ClickPipes.

Wire up the four groups of API surface landed in the drift fixes
(#298/#299/#300) to user-facing CLI commands:

1. ClickPipe object-storage ingestion control:
   `--skip-initial-load` and `--start-after` (continuous/SQS pipes only).
   `--skip-initial-load` requires `--queue-url`; `--start-after` conflicts
   with `--skip-initial-load`.

2. Service horizontal autoscaling on `service create`/`service scale`:
   `--min-replicas`/`--max-replicas`/`--autoscaling-mode`. The horizontal
   pair is mutually exclusive with the vertical flags. Infers `horizontal`
   when the replica pair is present without an explicit mode, and rejects
   min-without-max (and vice versa) before any network call.

3. ClickPipe MySQL `--server-id` for CDC replication.

4. ClickPipe schema discovery (beta): new `clickpipe schema-discover`
   command with `kafka`/`kinesis` subcommands that POST to
   `/clickpipes/schemaDiscovery` and render the inferred fields. Source
   connection flags are shared with the `create` subcommands via
   `KafkaSourceFields`/`KinesisSourceFields` flatten structs, so there is
   no `service_id` positional clash and no destination fields.

Adds `AutoscalingMode::VALUES` to the API library (drift-guarded by the
analyzer enum-values check) and a `click_pipe_schema_discovery` wrapper
on `CloudClient`.

Tests:
- bin: build_*_request unit tests (minimal + maximal) for horizontal
  autoscaling on create and scale, plus resolve_horizontal_autoscaling
  edge cases; Cli::try_parse_from coverage for all new flags.
- wiremock: object-storage skipInitialLoad/startAfter, MySQL serverId,
  and schema-discovery POST body shape for kafka + kinesis.
@sdairs
sdairs requested review from iskakaushik and rndD as code owners July 17, 2026 15:31
@sdairs
sdairs temporarily deployed to cloud-integration July 17, 2026 15:31 — with GitHub Actions Inactive
Comment thread crates/clickhousectl/src/cloud/commands.rs Outdated
Comment thread crates/clickhousectl/src/cloud/cli.rs Outdated
Comment thread crates/clickhousectl/src/cloud/commands.rs Outdated
Comment thread crates/clickhousectl/src/cloud/commands.rs Outdated
Comment thread crates/clickhousectl/src/cloud/cli.rs
Comment thread crates/clickhousectl/src/cloud/commands.rs
- resolve_horizontal_autoscaling no longer injects autoscalingMode
  "horizontal" when --min-replicas/--max-replicas are given without an
  explicit --autoscaling-mode. The API resolves an omitted mode itself,
  and an equal band with the mode omitted is accepted as a vertical
  fixed replica count without the horizontal entitlement — inferring
  horizontal changed those semantics.
- service scale human output now reports the autoscaling mode and, for
  horizontal services, the replica band and per-replica memory instead
  of only the vertical fields.
- --iterator-timestamp values above i64::MAX now fail with a clear
  error instead of silently wrapping negative via `as i64`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sdairs
sdairs temporarily deployed to cloud-integration July 20, 2026 21:07 — with GitHub Actions Inactive
Comment thread crates/clickhousectl/src/cloud/commands.rs Outdated
Verified against the live API with an OAuth bearer token: the gateway
rejects POST /clickpipes/schemaDiscovery with "This endpoint is not
available for JWT authentication". The command is side-effect-free but
requires API-key auth, so is_write_command must return true to fail
fast with the API-key guidance (exit code 4) instead of a doomed
network round-trip. Moves the test case from the read-only list to the
destructive list accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9510dc4. Configure here.

Comment thread crates/clickhousectl/src/cloud/cli.rs
Relax the autoscaling clap conflicts so `--autoscaling-mode` and the
memory flags combine with either mode's fields — the scaling PATCH
accepts a mode switch with its target fields in one request, and
horizontal requires equal min/max memory in the same call. Only the
contradictory `--num-replicas` vs `--min-replicas`/`--max-replicas`
conflict remains.

Print no mode-specific scale output for an unrecognized autoscaling
mode instead of falling through to the vertical fields.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR exposes newly-added ClickHouse Cloud API surface in the clickhousectl CLI, covering ClickPipes ingestion controls, MySQL replication server ID, schema discovery (beta), and service horizontal autoscaling—aligning the CLI with recent OpenAPI drift remediation work.

Changes:

  • Added ClickPipe object-storage ingestion control flags (--skip-initial-load, --start-after) and MySQL --server-id, including wire-shape coverage.
  • Added service horizontal autoscaling flags (--min-replicas, --max-replicas, --autoscaling-mode) with shared request-building logic for service create and service scale.
  • Introduced clickpipe schema-discover (Kafka/Kinesis) and a CloudClient wrapper for the schema-discovery endpoint; updated README usage/docs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
README.md Documents new autoscaling, ClickPipe ingestion-control, MySQL server-id, and schema-discover usage.
crates/clickhousectl/tests/cli_request_shape_test.rs Adds wiremock tests asserting new request-body fields for S3 ingestion control, MySQL serverId, and schema discovery POST shape.
crates/clickhousectl/src/main.rs Wires the new clickpipe schema-discover command into cloud dispatch.
crates/clickhousectl/src/cloud/commands.rs Implements request building/serialization for new flags and adds schema discovery handler; refactors Kafka/Kinesis source construction.
crates/clickhousectl/src/cloud/client.rs Adds a CloudClient::click_pipe_schema_discovery wrapper.
crates/clickhousectl/src/cloud/cli.rs Adds new CLI flags/commands and clap parsing tests; classifies schema-discover as “write” for auth gating.
crates/clickhouse-cloud-api/src/models.rs Adds AutoscalingMode::VALUES for CLI validation / analyzer drift-guarding.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/clickhousectl/src/cloud/commands.rs
Comment thread crates/clickhousectl/src/cloud/commands.rs
Comment thread crates/clickhousectl/src/cloud/commands.rs
Comment thread crates/clickhousectl/src/cloud/commands.rs
Comment thread crates/clickhousectl/src/cloud/cli.rs
- Correct build_kafka_source/build_kinesis_source doc comments to the
  actual positional command shape (no --source flag).
- Align the clickpipe_schema_discover doc comment with its write
  classification: side-effect-free, but the gateway rejects
  OAuth/Bearer so API key auth is required.
- Drop redundant after_help lines (auth note, --json hint) from the
  schema-discover clap command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sdairs
sdairs temporarily deployed to cloud-integration July 21, 2026 11:06 — with GitHub Actions Inactive
@sdairs
sdairs requested a review from rndD July 21, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decide CLI exposure for new API fields from OpenAPI drift #287

3 participants