Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ The current scaffold parses these global flags before subcommands:
- `--output json|table`
- `--yes`

`--yes` explicitly approves a mutating OpenAPI request without an interactive prompt. It does not
skip target-plan construction, validation, redaction, or operation reporting.

## Guided setup

Use `apollo init` for first-time setup. It creates a profile, writes non-secret profile metadata to
Expand Down Expand Up @@ -274,7 +277,7 @@ Structured JSON errors include:
- `code`: stable error code
- `category`: stable category
- `message`: human-readable message
- optional non-sensitive details such as `command`, `profile`, `path`, or `follow_up_issue`
- optional non-sensitive details such as `command`, `profile`, `path`, or `operation`

Current error categories:

Expand All @@ -289,6 +292,40 @@ Current error categories:
- `confirmation_required`
- `unsupported_operation`

Process exit statuses are stable at the following level:

- `0`: success
- `1`: runtime or operation failure, including authentication, validation, network/server, and
confirmation failures
- `2`: command-line parse or usage failure

Use the structured JSON `error.code` and `error.category` fields when automation needs a more
specific failure reason than the process exit status.

## Mutation safety

Before a built-in namespace, config, release, or raw API mutation, the CLI constructs a redacted
operation plan from the selected profile/server and the command target. Plans include the fields
available for that operation, such as app, env, cluster, namespace, config key/count, release IDs,
or a sanitized raw OpenAPI method and path. Config values, request bodies, query values, tokens, and
Authorization headers are not included.

In interactive table mode, a mutation without `--yes` writes the plan and a `[y/N]` prompt to
stderr. Only `y` or `yes` executes the request; `n`, `no`, blank input, or EOF rejects it. In
non-interactive mode and in JSON mode, mutations require `--yes`; otherwise the CLI returns a
`confirmation_required` error whose `operation` field contains the redacted plan. Rejection occurs
before any OpenAPI request is sent.

Namespace creation may perform read-only preflight requests after that initial approval. If Apollo
resolves a different effective namespace name, such as adding an organization prefix to a public
namespace, the CLI shows the resolved plan and requires approval again before either mutation is
sent. If the selected profile, server, or output mode changes after approval, the CLI aborts before
sending an OpenAPI request and asks the caller to review the new context.

With `--yes`, table mode still writes the plan before the request. A successful JSON response stays
one valid JSON document and preserves the existing top-level `status` and `data` fields while adding
the top-level `operation` plan.

## OpenAPI behavior

The first v0 implementation uses a small generic HTTP client instead of a generated SDK. This keeps
Expand All @@ -309,8 +346,8 @@ Path and payload mapping follows the current Apollo Portal OpenAPI contract, inc
- `POST /openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases`
- `PUT /openapi/v1/envs/{env}/releases/{releaseId}/rollback`

Mutating commands require `--yes`. Without it, the CLI returns `confirmation_required` before
opening a network connection.
Mutating command confirmation and operation-plan behavior are described in
[Mutation safety](#mutation-safety).

## Binary releases

Expand Down
24 changes: 22 additions & 2 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ apollo api post /openapi/v1/apps --body '{"app":{"appId":"sample-app"}}' --yes
- `--output json|table`
- `--yes`

`--yes` 表示在不显示交互提示的情况下显式批准一次 OpenAPI 变更请求。它不会跳过目标计划构建、参数校验、脱敏或操作信息输出。

## 引导式初始化

首次使用时推荐执行 `apollo init`。它会创建 profile,将非敏感 profile 元数据写入 `config.toml`,并且可以通过凭据存储抽象保存 Apollo OpenAPI token。
Expand Down Expand Up @@ -242,7 +244,7 @@ apollo --profile dev auth capabilities
- `code`:稳定错误码
- `category`:稳定错误分类
- `message`:人类可读错误信息
- 可选的非敏感详情,例如 `command`、`profile`、`path` 或 `follow_up_issue`
- 可选的非敏感详情,例如 `command`、`profile`、`path` 或 `operation`

当前错误分类:

Expand All @@ -257,6 +259,24 @@ apollo --profile dev auth capabilities
- `confirmation_required`
- `unsupported_operation`

进程退出状态在以下层级保持稳定:

- `0`:成功
- `1`:运行期或操作失败,包括鉴权、校验、网络/服务端和确认失败
- `2`:命令行解析或用法错误

当自动化调用方需要比进程退出状态更具体的失败原因时,应使用结构化 JSON 中的 `error.code` 和 `error.category`。

## 变更安全

在执行内置 namespace、config、release 或 raw API 变更前,CLI 会根据选中的 profile/server 和命令目标构建一份脱敏操作计划。计划会按操作类型包含可用字段,例如 app、env、cluster、namespace、配置 key/数量、release ID,或经过净化的 raw OpenAPI method 和 path。计划不会包含配置值、请求 body、query 值、token 或 Authorization header。

在交互式 table 模式中,未传 `--yes` 的变更会把计划和默认拒绝的 `[y/N]` 提示写到 stderr。只有输入 `y` 或 `yes` 才会执行;输入 `n`、`no`、空行或遇到 EOF 都会拒绝。在非交互模式和 JSON 模式中,变更必须显式传入 `--yes`;否则 CLI 返回 `confirmation_required`,其 `operation` 字段包含脱敏计划。拒绝发生在任何 OpenAPI 请求发送之前。

namespace 创建只会在首次批准后发送只读预检请求。如果 Apollo 解析出的最终 namespace 名称发生变化,例如为公共 namespace 添加组织前缀,CLI 会展示解析后的计划,并在发送任何变更请求前再次要求批准。如果批准后选中的 profile、server 或输出模式发生变化,CLI 会在发送 OpenAPI 请求前中止,并要求调用方重新检查新的运行上下文。

传入 `--yes` 时,table 模式仍会在请求前输出计划。成功的 JSON 输出仍是一个完整 JSON 文档,并保留现有顶层 `status` 和 `data` 字段,同时新增顶层 `operation` 计划。

## OpenAPI 行为

第一版 v0 实现使用一个小型通用 HTTP client,而不是生成式 SDK。这样可以让 CLI 与 Apollo 服务端仓库解耦,同时仍然保证所有内置资源命令都限定在 `/openapi/v1/*`。
Expand All @@ -275,7 +295,7 @@ apollo --profile dev auth capabilities
- `POST /openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases`
- `PUT /openapi/v1/envs/{env}/releases/{releaseId}/rollback`

变更类命令要求传 `--yes`。如果没有传,CLI 会在建立网络连接之前返回 `confirmation_required`
变更类命令的确认和操作计划行为见[变更安全](#变更安全)

## 可执行文件发布

Expand Down
2 changes: 1 addition & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub struct GlobalOptions {
#[arg(
long,
global = true,
help = "Skip confirmation prompts for mutating OpenAPI requests"
help = "Approve mutating OpenAPI requests without an interactive prompt"
)]
pub yes: bool,
}
Expand Down
Loading
Loading