Skip to content

fix(api): remediate remaining OpenAPI drift — Postgres backups, whoami, Kafka Glue registry (#1027) - #1039

Open
sdairs wants to merge 3 commits into
claude/cli-saved-queries-1029from
claude/drift-delta-api-1027
Open

sdairs wants to merge 3 commits into
claude/cli-saved-queries-1029from
claude/drift-delta-api-1027

Conversation

@sdairs

@sdairs sdairs commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

Part of #1027. Stacked on #1036 (→ #1035 → #1028).

After #1028 was opened, the live spec drifted further. On the head of #1036 the drift dry run still reported 29 actionable findings. This PR fixes all of them, and the dry run now reports No actionable drift. It is library-only; the CLI exposure is in the next PR, for #1038.

Changes

  • Snapshot: clickhouse_cloud_openapi.json is refreshed from the live spec, byte-identical to it. This clears the stale-snapshot findings.
  • ActivityType: adds postgres_action.
  • Backup encryption (private preview):
    • New BackupEncryptionConfig, a BTreeMap<String, serde_json::Value> alias. The spec defines it as an opaque additionalProperties object whose shape depends on the provider, so it is passed through verbatim.
    • New ServicePostRequest.backup_encryption_config, omitted from the JSON when unset.
    • The analyzer marks it required because it is a bare $ref. The spec's backupId text makes it conditional (required only for a backup in your own bucket, omitted otherwise), so it stays Option. A documented optionality exemption in config.rs covers this.
  • Kafka schema registry is now a Confluent/Glue union (breaking for Rust callers):
    • ClickPipeKafkaSchemaRegistry is the response type and ClickPipeMutateKafkaSchemaRegistry the request type. Both are now discriminated_union! on type. The variants are ClickPipeKafkaConfluentSchemaRegistry / ClickPipeMutateKafkaConfluentSchemaRegistry and ClickPipeKafkaGlueSchemaRegistry[Response].
    • A payload with no type still parses as Confluent, as older payloads did. If such a payload carries any glue* key it goes to Unknown instead of being misread. An unrecognized type is kept as Unknown(Value).
    • The Glue schema is used in both directions, so it is split into {Name} / {Name}Response. TryFrom converts the response to the request.
    • The authentication enums are renamed to follow their new parent schemas.
    • The crate README has a migration note.
    • CLI: compile fix only. It still builds a Confluent registry, and the request on the wire is unchanged.
  • Postgres backup list (beta):
    • New postgres_service_backup_get_list(org_id, postgres_id, cursor, limit), which returns Vec<PostgresBackup> with the limit/totalCount/nextCursor envelope. The (cursor, limit) signature follows saved_query_list.
    • New PostgresBackup { key, last_modified }.
  • Whoami (beta):
    • New whoami_get(). It takes no organization, and its permission metadata is empty (required_permissions: &[]), because the operation inherits the spec's global basic auth with no scopes.
    • Whoami is a union on actorType: WhoamiUser (with organizations: Vec<WhoamiOrganization>) or WhoamiApiKey. An unknown, missing or ill-fitting actor goes to Unknown(Value).
    • New domain files: src/client/whoami.rs and src/models/whoami.rs.
  • Metadata: the operation descriptors for both new operations are generated into meta/operations.rs, with ALL kept sorted, and BETA_OPERATIONS is regenerated.
  • Classifiers: both scripts and their fixtures map the new whoami files. The Cloud classifier maps them to the organization suite.
  • Crate README: updated. The root README is unchanged.

Tests

  • models_test:
    • For every new response type, a missing key and an explicit null both give None.
    • Union dispatch: Confluent with no type, an explicit type, Glue, the Glue-key guard, and unknown values.
    • The exact request JSON for each registry variant, plus request strictness.
    • An opaque round-trip of the encryption config, nested data included.
    • The new enum values.
  • client_test (wiremock):
    • Backup list: cursor/limit encoding (including a special-character cursor and the no-query case), the envelope fields, and a last page with nextCursor: null.
    • Whoami: the user (bearer) and API-key (basic) variants, and an unknown actor.
    • Error paths for both methods.
  • model_facade_test: covers the new export paths.
  • Live integration: new steps were added but not run: a Backups step in integration_postgres_test.rs, and a Whoami step in integration_org_test.rs that expects the suite's API key to resolve to WhoamiApiKey for the configured org.

Gates

  • cargo fmt and library clippy (--all-targets) are clean, as are both clickhousectl clippy configurations.
  • cargo check --workspace --all-features passes.
  • Library and analyzer tests pass, as do the 96 Python classifier tests and cargo test -p clickhousectl.
  • python3 scripts/check-openapi-drift.py --dry-run reports No actionable drift.

The first commit refreshes the snapshot before the remaining models exist, so the spec-coverage tests fail at that commit alone. They pass at the PR head.

🤖 Generated with Claude Code

sdairs and others added 3 commits October 1, 2026 18:57
…postgres_action (#1027)

Replace the vendored OpenAPI snapshot with the live document and remediate
the small model drift it introduces:

- ActivityType: postgres_action
- BackupEncryptionConfig: new opaque pass-through alias
  (BTreeMap<String, serde_json::Value>) for a backup's encryption_config.json,
  whose shape is versioned and provider-specific
- ServicePostRequest.backupEncryptionConfig (optional, skipped when None);
  the bare $ref trips the description requiredness heuristic, so it gets a
  documented optionality exemption: backupId's description makes it required
  only for own-bucket backups and forbidden otherwise

The Kafka schema registry, Postgres backup list and whoami findings from the
refreshed snapshot are remediated in follow-up commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The refreshed OpenAPI snapshot makes ClickPipeKafkaSchemaRegistry (response)
and ClickPipeMutateKafkaSchemaRegistry (request) oneOf unions over Confluent
and AWS Glue registries. Model both as discriminated unions on `type`, where
an absent `type` selects Confluent (the API default and legacy payloads)
unless a Glue-only key is present, and unknown types stay lossless in
Unknown(Value).

New types: ClickPipeKafkaConfluentSchemaRegistry (response),
ClickPipeMutateKafkaConfluentSchemaRegistry (request), and the split pair
ClickPipeKafkaGlueSchemaRegistry / ClickPipeKafkaGlueSchemaRegistryResponse
with a TryFrom write-back. Authentication enums follow the renamed variant
schemas. The CLI keeps building a Confluent registry without `type`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add the two remaining beta operations from the live OpenAPI spec:

- postgres_service_backup_get_list (GET /v1/organizations/{organizationId}/
  postgres/{postgresId}/backups) takes an optional cursor and limit and
  returns ApiResponse<Vec<PostgresBackup>>, with limit, totalCount and
  nextCursor on the envelope like saved_query_list. PostgresBackup is
  all-Option (key, lastModified as DateTime<Utc>).
- whoami_get (GET /v1/whoami) is organization-independent and inherits the
  global basicAuth requirement with no permission scopes. It returns the
  Whoami response union, dispatched on actorType through
  discriminated_union! to WhoamiUser ("user") or WhoamiApiKey ("apiKey");
  an unknown, absent or misshapen payload is kept verbatim in
  Unknown(Value). WhoamiUser, WhoamiApiKey and WhoamiOrganization are
  all-Option; actorType is a single-value enum with an Unknown(String)
  catch-all.

Regenerate BETA_OPERATIONS and the operation descriptors
(POSTGRES_SERVICE_BACKUP_GET_LIST, WHOAMI_GET with no required
permissions), map the new whoami domain files in both CI classifiers, and
cover the methods with wiremock, model, facade and live lifecycle tests.
The drift dry run now reports zero actionable drift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant