Skip to content

feat(tencent): add --format json to clanker tencent list <type>#179

Merged
rafeegnash merged 1 commit into
masterfrom
feat/tencent-list-json
May 27, 2026
Merged

feat(tencent): add --format json to clanker tencent list <type>#179
rafeegnash merged 1 commit into
masterfrom
feat/tencent-list-json

Conversation

@rafeegnash
Copy link
Copy Markdown
Collaborator

Summary

Adds a --format flag (table | json, default table) to clanker tencent list <type>. JSON mode dispatches to the existing JSON* methods on *tencent.Client — the same canonical data source the in-process HTTP API surfaces at /api/v1/tencent/resources/{type}.

Why

clanker-cloud is building Tencent provider support (clankercloud/clanker-cloud PR #470 onward) and needs --json output to shell out cleanly. Without this flag the backend would have to either parse tabwriter output (brittle) or spawn clanker server as a managed sidecar (lifecycle complexity that was explicitly considered and rejected). This change is the smallest possible surface to unblock that work.

Behaviour

  • clanker tencent list cvm — unchanged (table)
  • clanker tencent list cvm --format json — single-region JSON array (matches the HTTP API shape exactly)
  • clanker tencent list cvm --format json --all-regions — explicit envelope:
    {
      "regions": [
        {"region": "ap-singapore", "data": [...]},
        {"region": "ap-tokyo", "data": [...]}
      ],
      "errors": [
        {"region": "ap-shanghai-fsi", "error": "..."}
      ]
    }
    Per-region errors so a single regional outage doesn't poison the whole sweep.
  • clanker tencent list subnets --format json — returns a guidance error pointing the user at vpc --format json (subnets are embedded in the VPC summary, no dedicated JSON method).
  • clanker tencent list cvm --format xml — clear error: unsupported --format "xml" (use 'table' or 'json').

Test plan

  • go test ./internal/tencent/ -run TestEmitTypedJSON — passes (dispatch + subnets guidance)
  • go vet ./... clean
  • gofmt -s -l . empty
  • clanker tencent list cvm --format json --help shows the new flag in the rendered help
  • clanker tencent list cvm (no format) still emits the table
  • clanker tencent list cvm --format xml errors out with a clear message (once creds are present — the credential check is intentionally first)
  • Live smoke against real Tencent creds — JSON output should match the existing HTTP API response shape byte-for-byte (both call the same JSONX methods)

Notes for reviewers

  • All new logic is in internal/tencent/list_json.go (clean dispatch table). The existing static_commands.go change is two flag additions plus a single short-circuit at the top of the list RunE.
  • Backward-compatible: every existing CLI invocation behaves identically.
  • The format-validation happens after credential resolution by design — credentials are a more fundamental error to surface first, so a typo in --format returns the credential message rather than a format-validation message when both are wrong.

The existing JSON-emitting methods on *tencent.Client (JSONCVMs,
JSONVPCs, JSONSecurityGroups, ...) are what the HTTP API in
`clanker server` surfaces at /api/v1/tencent/resources/{type}. They
were the canonical data source for programmatic consumers but had no
CLI affordance — `clanker tencent list cvm` only printed a tabwriter
table, so any pipeline that wanted JSON had to either parse the table
or stand up the full HTTP server.

Add a --format flag (table | json, default table) on the list
subcommand. JSON mode dispatches to the corresponding JSONX method
via a new listAsJSON / emitTypedJSON pair in internal/tencent/list_json.go.

Multi-region behaviour: --format json --all-regions emits an explicit
envelope { "regions": [{"region": "<code>", "data": <json>}, ...],
"errors": [{"region": "<code>", "error": "..."}, ...] }. Errors are
per-region so a single regional outage doesn't poison the whole sweep.

Subnets type returns a guidance message ("use `tencent list vpc
--format json` and read the embedded Subnets field") rather than a
generic "unknown type" — subnets don't have a dedicated JSON method
because they're embedded in the VPC summary.

Why now: clanker-cloud Phase b (Tencent backend integration) shells
out to `clanker tencent list <type> --json` for inventory. Without
this flag the backend would have to either parse table output (brittle)
or spawn `clanker server` as a sidecar (lifecycle complexity).

Tests cover the dispatch arms (unknown type, subnets guidance message).
go vet + gofmt -s clean. Backward-compatible: existing callers with no
--format flag still get the table output.
@rafeegnash rafeegnash merged commit 641ebdd into master May 27, 2026
5 checks passed
@rafeegnash rafeegnash deleted the feat/tencent-list-json branch May 27, 2026 14:00
rafeegnash added a commit that referenced this pull request May 28, 2026
…180)

Same pattern as the --format flag on `tencent list` (PR #179) — the
existing table renderer is preserved by default, and JSON mode is
opt-in via --format json. The JSON envelope is the canonical wire
shape consumed by the clanker-cloud Tencent cost.Provider.

Why: clanker-cloud Phase d wires Tencent into the Cost Explorer.
Without --format json on these subcommands the backend would have to
parse tabwriter output to extract per-service spend, which is brittle
and loses the precision of the Tencent SDK's string-encoded decimals.

Wire shapes:

  cost by-product --format json:
    { month, items: [{product, real_cost, cash, incentive, voucher, pct}], total }

  cost top --format json:
    { month, top, items: [{product, resource_id, name, region, pay_mode, action, cost}] }

Internals refactor: both list functions now split into a buildXReport
function that returns the typed struct and a writeXTable helper that
preserves the historical text output. listBillByProduct/Top stays the
single entry point and just routes by format. No external callers
depend on the old signatures because both were only invoked from
their respective cobra RunE.

Tests: JSON round-trip pins both shapes against drift.
go vet + gofmt -s clean; existing CLI behaviour unchanged.

Co-authored-by: nash <nash@clankercloud.ai>
rephapeng added a commit to rephapeng/clanker that referenced this pull request May 28, 2026
Upstream merged PR bgdnvk#165 (Tencent provider) and added work on top:
k8s SRE playbooks (bgdnvk#174), SRE agent fix (bgdnvk#177), tree-wide gofmt -s
(bgdnvk#176), README (bgdnvk#175), and three Tencent CLI features the fork lacked
— `list --format json` (bgdnvk#179), `cost --format json` (bgdnvk#180), and
security-scan CLI subcommands (bgdnvk#181).

Conflict resolution: all 16 conflicts resolved to upstream's side.
14 were pure gofmt whitespace from bgdnvk#176 (identical code); billing.go
and static_commands.go were upstream supersets adding the JSON/security
CLI surface with no fork-unique code lost. Fixed a duplicate tencent
import in cmd/ask.go left by the auto-merge.

Verified in Docker (golang:1.25, -mod=mod): gofmt clean, go build ./...,
go vet ./..., and go test ./... all pass.
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