aukeys-opscli 0.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aukeys_opscli-0.0.6.dist-info/METADATA +15 -0
- aukeys_opscli-0.0.6.dist-info/RECORD +92 -0
- aukeys_opscli-0.0.6.dist-info/WHEEL +4 -0
- aukeys_opscli-0.0.6.dist-info/entry_points.txt +2 -0
- opscli/__init__.py +9 -0
- opscli/amazon/__init__.py +13 -0
- opscli/amazon/cli.py +5 -0
- opscli/amazon/client.py +5 -0
- opscli/amazon/commands/__init__.py +1 -0
- opscli/amazon/commands/cli.py +200 -0
- opscli/amazon/domain/__init__.py +25 -0
- opscli/amazon/domain/exceptions.py +73 -0
- opscli/amazon/domain/models.py +74 -0
- opscli/amazon/exceptions.py +21 -0
- opscli/amazon/manager.py +5 -0
- opscli/amazon/models.py +5 -0
- opscli/amazon/parser.py +5 -0
- opscli/amazon/scraper.py +5 -0
- opscli/amazon/scraping/__init__.py +12 -0
- opscli/amazon/scraping/parser.py +66 -0
- opscli/amazon/scraping/scraper.py +315 -0
- opscli/amazon/services/__init__.py +5 -0
- opscli/amazon/services/manager.py +105 -0
- opscli/amazon/transport/__init__.py +5 -0
- opscli/amazon/transport/client.py +77 -0
- opscli/auth/__init__.py +79 -0
- opscli/auth/cli.py +255 -0
- opscli/auth/commands/__init__.py +1 -0
- opscli/auth/commands/cli.py +5 -0
- opscli/auth/config.py +55 -0
- opscli/auth/core/__init__.py +1 -0
- opscli/auth/core/device_flow.py +80 -0
- opscli/auth/core/system_registry.py +89 -0
- opscli/auth/core/token_manager.py +167 -0
- opscli/auth/domain/__init__.py +23 -0
- opscli/auth/domain/exceptions.py +33 -0
- opscli/auth/exceptions.py +23 -0
- opscli/auth/storage/__init__.py +1 -0
- opscli/auth/storage/credential_store.py +163 -0
- opscli/auth/storage/crypto.py +67 -0
- opscli/cli.py +36 -0
- opscli/config.py +3 -0
- opscli/query/__init__.py +6 -0
- opscli/query/cli.py +5 -0
- opscli/query/client.py +5 -0
- opscli/query/commands/__init__.py +1 -0
- opscli/query/commands/cli.py +140 -0
- opscli/query/domain/__init__.py +23 -0
- opscli/query/domain/exceptions.py +73 -0
- opscli/query/domain/models.py +21 -0
- opscli/query/exceptions.py +21 -0
- opscli/query/manager.py +5 -0
- opscli/query/models.py +5 -0
- opscli/query/services/__init__.py +5 -0
- opscli/query/services/manager.py +373 -0
- opscli/query/transport/__init__.py +5 -0
- opscli/query/transport/client.py +57 -0
- opscli/skills/__init__.py +37 -0
- opscli/skills/cli.py +5 -0
- opscli/skills/commands/__init__.py +1 -0
- opscli/skills/commands/cli.py +389 -0
- opscli/skills/detector.py +5 -0
- opscli/skills/discovery/__init__.py +5 -0
- opscli/skills/discovery/detector.py +225 -0
- opscli/skills/domain/__init__.py +23 -0
- opscli/skills/domain/exceptions.py +51 -0
- opscli/skills/domain/models.py +144 -0
- opscli/skills/exceptions.py +5 -0
- opscli/skills/manager.py +5 -0
- opscli/skills/models.py +19 -0
- opscli/skills/services/__init__.py +5 -0
- opscli/skills/services/manager.py +276 -0
- opscli/skills/sync/__init__.py +5 -0
- opscli/skills/sync/updater.py +274 -0
- opscli/skills/templates/ops-amazon/SKILL.md +181 -0
- opscli/skills/templates/ops-amazon/data/VERSION.json +4 -0
- opscli/skills/templates/ops-auth/SKILL.md +466 -0
- opscli/skills/templates/ops-auth/data/VERSION.json +4 -0
- opscli/skills/templates/ops-dataset-query/SKILL.md +691 -0
- opscli/skills/templates/ops-dataset-query/data/VERSION.json +4 -0
- opscli/skills/templates/ops-dataset-query/data/dataset_fields.csv +1 -0
- opscli/skills/templates/ops-dataset-query/data/datasets.csv +1 -0
- opscli/skills/templates/ops-dataset-query/data/query_metadata.json +4 -0
- opscli/skills/templates/ops-dataset-query/references//346/225/260/346/215/256/346/237/245/350/257/242/346/234/215/345/212/241/345/274/200/345/217/221/350/257/264/346/230/216/346/226/207/346/241/243.md +1126 -0
- opscli/skills/templates/ops-dataset-query/scripts/core.py +140 -0
- opscli/skills/templates/ops-dataset-query/scripts/query.py +145 -0
- opscli/skills/templates/ops-dataset-query/scripts/search.py +36 -0
- opscli/skills/templates/ops-dataset-query/scripts/updater.py +106 -0
- opscli/skills/templates/ops-skills/SKILL.md +494 -0
- opscli/skills/templates/ops-skills/data/VERSION.json +4 -0
- opscli/skills/updater.py +5 -0
- opscli/version.py +19 -0
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-auth
|
|
3
|
+
description: 管理 Aukeys 内部系统的 OAuth2 登录授权与 JWT Token
|
|
4
|
+
version: v1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ops-auth
|
|
8
|
+
|
|
9
|
+
管理 Aukeys 内部系统的 OAuth2 登录授权与 JWT Token,所有操作通过 `opscli auth` 子命令执行。
|
|
10
|
+
|
|
11
|
+
> **知识来源**:本文档综合了代码库架构分析(codebase_analysis,高置信度)和官方命令参考文档(documentation,高置信度),两个来源一致,无冲突。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 何时使用本 Skill
|
|
16
|
+
|
|
17
|
+
以下场景应使用 `ops-auth` Skill:
|
|
18
|
+
|
|
19
|
+
- **首次登录**:需要通过 Device Flow 完成 OAuth2 授权
|
|
20
|
+
- **Token 管理**:获取、校验、刷新各系统的 JWT
|
|
21
|
+
- **认证排查**:遇到 401、未登录、Token 过期等认证报错时
|
|
22
|
+
- **系统管理**:查看、添加、同步、移除已注册系统
|
|
23
|
+
- **脚本集成**:在 shell 脚本中获取 JWT 传递给其他命令
|
|
24
|
+
- **Python SDK 集成**:通过 `AuthClient` 在代码中直接获取认证信息
|
|
25
|
+
- **多环境切换**:添加自定义系统实例(如 staging 环境)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 关键概念
|
|
30
|
+
|
|
31
|
+
### Token 三态
|
|
32
|
+
|
|
33
|
+
| 状态 | 条件 | 行为 |
|
|
34
|
+
|------|------|------|
|
|
35
|
+
| `valid` | 距过期 > 300s | 直接返回 |
|
|
36
|
+
| `expiring_soon` | 距过期 ≤ 300s | 自动触发刷新 |
|
|
37
|
+
| `expired` | 已过期 | 需重新获取(可能需要重新登录) |
|
|
38
|
+
|
|
39
|
+
### 双层并发锁
|
|
40
|
+
|
|
41
|
+
Token 管理内置双层并发保护,无需调用方额外处理并发:
|
|
42
|
+
- **Layer 1**:`threading.Lock`(防同进程多线程并发)
|
|
43
|
+
- **Layer 2**:`fcntl.flock()`(防多 CLI 进程并发,Windows 自动跳过)
|
|
44
|
+
|
|
45
|
+
### 凭证存储优先级
|
|
46
|
+
|
|
47
|
+
1. **macOS Keychain**(优先,服务名:`opscli-auth`)
|
|
48
|
+
2. **AES-256-GCM 加密文件**(兜底,路径:`~/.config/opscli/credentials.bin`)
|
|
49
|
+
|
|
50
|
+
### 系统类型
|
|
51
|
+
|
|
52
|
+
| 类型 | 来源 | 是否可删除 |
|
|
53
|
+
|------|------|----------|
|
|
54
|
+
| `builtin` | 内置(ops、polaris) | 否 |
|
|
55
|
+
| `local` | 用户手动添加 | 是 |
|
|
56
|
+
| `ops_sync` | 从 ops 后端同步 | 自动更新 |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 内置系统
|
|
61
|
+
|
|
62
|
+
| 别名 | System Key | URL | 用途 |
|
|
63
|
+
|------|-----------|-----|------|
|
|
64
|
+
| `ops` | ops | https://ops.aukeys.com | 运营系统,数据查询、Skill 升级等 |
|
|
65
|
+
| `polaris` | polaris_sys | https://bi.aukeys.com | 刊登系统 |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 快速参考
|
|
70
|
+
|
|
71
|
+
### 登录与状态检查
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# 首次登录(Device Flow,自动打开浏览器)
|
|
75
|
+
opscli auth login
|
|
76
|
+
|
|
77
|
+
# 查看登录状态与所有系统 Token
|
|
78
|
+
opscli auth token status
|
|
79
|
+
|
|
80
|
+
# 环境检查 + 连通性诊断
|
|
81
|
+
opscli auth doctor
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Token 操作
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# 获取 JWT(纯文本,适合脚本)
|
|
88
|
+
opscli auth token get -s ops
|
|
89
|
+
opscli auth token get -s polaris
|
|
90
|
+
|
|
91
|
+
# 赋值给变量(常用模式)
|
|
92
|
+
TOKEN=$(opscli auth token get -s ops)
|
|
93
|
+
|
|
94
|
+
# 检查 Token 是否有效(不刷新)
|
|
95
|
+
opscli auth token check -s ops
|
|
96
|
+
# 输出: ✓ 有效 剩余 3500 秒
|
|
97
|
+
|
|
98
|
+
# 主动刷新单个系统
|
|
99
|
+
opscli auth token refresh -s ops
|
|
100
|
+
|
|
101
|
+
# 刷新所有系统
|
|
102
|
+
opscli auth token refresh --all
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 系统管理
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# 列出所有系统
|
|
109
|
+
opscli auth system list
|
|
110
|
+
|
|
111
|
+
# 从 ops 同步系统列表(需已登录)
|
|
112
|
+
opscli auth system sync
|
|
113
|
+
|
|
114
|
+
# 添加自定义系统(如 staging 环境)
|
|
115
|
+
opscli auth system add --alias my-ops --url https://ops-staging.aukeys.com
|
|
116
|
+
opscli auth system add --alias test-env --url https://test.aukeys.com --key test_env
|
|
117
|
+
|
|
118
|
+
# 移除自定义系统
|
|
119
|
+
opscli auth system remove --alias my-ops
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Python SDK
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from opscli import AuthClient
|
|
126
|
+
# 或等价写法
|
|
127
|
+
from opscli.auth import AuthClient
|
|
128
|
+
|
|
129
|
+
client = AuthClient()
|
|
130
|
+
|
|
131
|
+
# 获取 JWT(自动刷新)
|
|
132
|
+
token = client.get_token("ops")
|
|
133
|
+
|
|
134
|
+
# 检查登录状态
|
|
135
|
+
if client.is_authenticated():
|
|
136
|
+
print("已登录")
|
|
137
|
+
|
|
138
|
+
# 构建请求认证参数(同时返回 headers 和 cookies)
|
|
139
|
+
headers, cookies = client.build_request_auth("ops")
|
|
140
|
+
|
|
141
|
+
# 构建 session headers
|
|
142
|
+
headers = client.build_session_headers("ops")
|
|
143
|
+
|
|
144
|
+
# 强制刷新 Token
|
|
145
|
+
client.refresh_token("ops")
|
|
146
|
+
|
|
147
|
+
# 检查 Token 有效性
|
|
148
|
+
result = client.check_token("ops")
|
|
149
|
+
# result: {"valid": True, "expires_in": 3500}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 完整命令参考
|
|
155
|
+
|
|
156
|
+
### `opscli auth login`
|
|
157
|
+
|
|
158
|
+
发起 Device Flow 授权(RFC 8628),自动打开浏览器完成登录。登录成功后凭证写入本地,并自动执行系统同步。
|
|
159
|
+
|
|
160
|
+
**登录流程**:
|
|
161
|
+
1. 工具获取设备码并自动打开浏览器
|
|
162
|
+
2. 用户在浏览器确认授权(300 秒内完成)
|
|
163
|
+
3. 工具轮询获取 Token,写入本地存储
|
|
164
|
+
4. 自动执行 `system sync`
|
|
165
|
+
|
|
166
|
+
**输出示例**:
|
|
167
|
+
```
|
|
168
|
+
请在浏览器打开: https://ops.aukeys.com/device
|
|
169
|
+
输入验证码: ABCD-1234
|
|
170
|
+
等待授权中...(300 秒内完成)
|
|
171
|
+
✓ 授权成功!账号:user@aukeys.com
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
opscli auth login
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### `opscli auth logout`
|
|
181
|
+
|
|
182
|
+
清除本地所有凭证(Keychain + 加密文件),需要重新登录。
|
|
183
|
+
|
|
184
|
+
**输出示例**:
|
|
185
|
+
```
|
|
186
|
+
✓ 已退出,本地凭证已清除
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
opscli auth logout
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
### `opscli auth doctor`
|
|
196
|
+
|
|
197
|
+
检查登录状态与各系统连通性,输出诊断报告,适合排查认证问题。
|
|
198
|
+
|
|
199
|
+
**输出示例**:
|
|
200
|
+
```
|
|
201
|
+
opscli auth 环境检查
|
|
202
|
+
|
|
203
|
+
✓ 已登录
|
|
204
|
+
✓ ops 可访问
|
|
205
|
+
✓ polaris 可访问
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
opscli auth doctor
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### `opscli auth token status`
|
|
215
|
+
|
|
216
|
+
查看当前登录状态与所有系统的 Token 情况(是否有效、过期时间等)。
|
|
217
|
+
|
|
218
|
+
**输出示例**:
|
|
219
|
+
```
|
|
220
|
+
已登录 user@aukeys.com
|
|
221
|
+
Session 过期:2025-04-23T10:00:00
|
|
222
|
+
|
|
223
|
+
别名 系统 Token 状态 剩余时间(s)
|
|
224
|
+
ops ops 有效 3542
|
|
225
|
+
polaris polaris_sys 有效 3500
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
opscli auth token status
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### `opscli auth token get`
|
|
235
|
+
|
|
236
|
+
获取指定系统的 JWT(纯文本输出),适合赋值给变量或传递给其他命令。
|
|
237
|
+
|
|
238
|
+
**参数**:
|
|
239
|
+
- `-s, --system TEXT`:系统别名(必填,如 ops、polaris)
|
|
240
|
+
|
|
241
|
+
**错误场景**:
|
|
242
|
+
- 未登录时输出错误并退出码 1
|
|
243
|
+
- 系统别名不存在时输出错误并退出码 1
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# 获取 ops 系统 Token
|
|
247
|
+
opscli auth token get -s ops
|
|
248
|
+
|
|
249
|
+
# 赋值给变量(推荐脚本用法)
|
|
250
|
+
TOKEN=$(opscli auth token get -s ops)
|
|
251
|
+
|
|
252
|
+
# 获取 polaris 系统 Token
|
|
253
|
+
opscli auth token get -s polaris
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
### `opscli auth token check`
|
|
259
|
+
|
|
260
|
+
检测指定系统的 JWT 是否有效(不刷新,仅校验本地 Token)。
|
|
261
|
+
|
|
262
|
+
**参数**:
|
|
263
|
+
- `-s, --system TEXT`:系统别名(必填)
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
opscli auth token check -s ops
|
|
267
|
+
# 输出: ✓ 有效 剩余 3500 秒
|
|
268
|
+
|
|
269
|
+
opscli auth token check -s polaris
|
|
270
|
+
# 若无效: ✗ 已过期或未获取(退出码 1)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### `opscli auth token refresh`
|
|
276
|
+
|
|
277
|
+
刷新 JWT,支持单个系统或全部系统。
|
|
278
|
+
|
|
279
|
+
**参数**:
|
|
280
|
+
- `-s, --system TEXT`:指定单个系统别名
|
|
281
|
+
- `--all`:刷新所有已登录系统的 Token
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# 刷新单个系统
|
|
285
|
+
opscli auth token refresh -s ops
|
|
286
|
+
|
|
287
|
+
# 刷新所有系统
|
|
288
|
+
opscli auth token refresh --all
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
### `opscli auth system list`
|
|
294
|
+
|
|
295
|
+
列出所有已注册系统(内置 + ops 同步 + 手动添加)。
|
|
296
|
+
|
|
297
|
+
**输出示例**:
|
|
298
|
+
```
|
|
299
|
+
别名 System Key URL 来源
|
|
300
|
+
ops ops https://ops.aukeys.com builtin
|
|
301
|
+
polaris polaris_sys https://bi.aukeys.com builtin
|
|
302
|
+
my-ops my_ops https://ops-staging.aukeys.com local
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
opscli auth system list
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### `opscli auth system sync`
|
|
312
|
+
|
|
313
|
+
从 ops 后端同步多实例系统列表(需已登录 ops)。登录时自动执行,一般无需手动调用。
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
opscli auth system sync
|
|
317
|
+
# 输出: ✓ 同步完成,共 3 个系统
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### `opscli auth system add`
|
|
323
|
+
|
|
324
|
+
手动添加自定义系统实例。
|
|
325
|
+
|
|
326
|
+
**参数**:
|
|
327
|
+
- `--alias TEXT`:系统别名(必填,用于 -s 参数)
|
|
328
|
+
- `--url TEXT`:系统 base URL(必填)
|
|
329
|
+
- `--key TEXT`:存储键,默认由 alias 生成(可选)
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# 添加 staging 环境
|
|
333
|
+
opscli auth system add --alias my-ops --url https://ops-staging.aukeys.com
|
|
334
|
+
|
|
335
|
+
# 指定自定义存储键
|
|
336
|
+
opscli auth system add --alias test-env --url https://test.aukeys.com --key test_env
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
### `opscli auth system remove`
|
|
342
|
+
|
|
343
|
+
移除手动添加的系统(内置系统 ops / polaris 不可移除)。
|
|
344
|
+
|
|
345
|
+
**参数**:
|
|
346
|
+
- `--alias TEXT`:系统别名(必填)
|
|
347
|
+
|
|
348
|
+
**注意**:尝试移除内置系统(ops、polaris)会报错并退出。
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
opscli auth system remove --alias my-ops
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## 典型工作流
|
|
357
|
+
|
|
358
|
+
### 入门:首次登录与验证
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
# 1. 发起 Device Flow 登录
|
|
362
|
+
opscli auth login
|
|
363
|
+
|
|
364
|
+
# 2. 确认登录状态
|
|
365
|
+
opscli auth token status
|
|
366
|
+
|
|
367
|
+
# 3. 验证连通性
|
|
368
|
+
opscli auth doctor
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### 进阶:脚本集成
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# 获取 Token 并传递给 curl
|
|
375
|
+
TOKEN=$(opscli auth token get -s ops)
|
|
376
|
+
curl -H "Authorization: Bearer $TOKEN" https://ops.aukeys.com/api/v1/data
|
|
377
|
+
|
|
378
|
+
# 先检查再使用(避免过期)
|
|
379
|
+
opscli auth token check -s ops && TOKEN=$(opscli auth token get -s ops)
|
|
380
|
+
|
|
381
|
+
# Token 刷新后再使用
|
|
382
|
+
opscli auth token refresh -s ops
|
|
383
|
+
TOKEN=$(opscli auth token get -s ops)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### 高级:多系统与 Python SDK
|
|
387
|
+
|
|
388
|
+
```python
|
|
389
|
+
from opscli import AuthClient
|
|
390
|
+
|
|
391
|
+
client = AuthClient()
|
|
392
|
+
|
|
393
|
+
# 为不同系统构建认证参数
|
|
394
|
+
ops_headers, ops_cookies = client.build_request_auth("ops")
|
|
395
|
+
polaris_headers, polaris_cookies = client.build_request_auth("polaris")
|
|
396
|
+
|
|
397
|
+
# 检查特定系统的 Token 状态
|
|
398
|
+
result = client.check_token("ops")
|
|
399
|
+
if not result["valid"]:
|
|
400
|
+
client.refresh_token("ops")
|
|
401
|
+
|
|
402
|
+
token = client.get_token("ops")
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## 常见错误排查
|
|
408
|
+
|
|
409
|
+
| 错误现象 | 解决方案 |
|
|
410
|
+
|---------|---------|
|
|
411
|
+
| 401 / 未登录 | `opscli auth login` |
|
|
412
|
+
| Token 过期 | `opscli auth token refresh -s <alias>` |
|
|
413
|
+
| 系统不可达 | `opscli auth doctor` 确认连通性 |
|
|
414
|
+
| 系统别名不存在 | `opscli auth system list` 查看可用别名 |
|
|
415
|
+
| Device Flow 超时(> 300s)| 重新执行 `opscli auth login` |
|
|
416
|
+
| 授权被拒绝 | 确认在浏览器页面点击了"允许",重新执行 `opscli auth login` |
|
|
417
|
+
| Keychain 不可用 | 自动降级到 AES-256-GCM 加密文件存储,无需干预 |
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Token 生命周期常量
|
|
422
|
+
|
|
423
|
+
| 常量 | 值 | 说明 |
|
|
424
|
+
|------|----|------|
|
|
425
|
+
| `REFRESH_THRESHOLD` | 300s | 距过期 5 分钟内自动刷新 |
|
|
426
|
+
| `MAX_JWT_TTL` | 86400s | 最大 JWT 有效期(24小时) |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## 本地配置文件
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
~/.config/opscli/
|
|
434
|
+
├── config.ini # 可选,覆盖服务地址(ops_url 等)
|
|
435
|
+
├── credentials.bin # AES-256-GCM 加密凭证(Keychain 不可用时)
|
|
436
|
+
├── .key # 256-bit 加密密钥,权限 600
|
|
437
|
+
├── systems.json # 用户自定义 + ops_sync 系统列表
|
|
438
|
+
└── .lock_<key> # 跨进程文件锁(运行时临时文件)
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**覆盖服务地址示例**(开发调试用):
|
|
442
|
+
|
|
443
|
+
```ini
|
|
444
|
+
# ~/.config/opscli/config.ini
|
|
445
|
+
[systems]
|
|
446
|
+
ops_url = http://localhost/api
|
|
447
|
+
ops_system_url = http://ops.cm
|
|
448
|
+
ops_token_endpoint = /api/v1/auth/cli-token
|
|
449
|
+
polaris_system_url = http://po2.cm
|
|
450
|
+
polaris_token_endpoint = /api/auth/cli-token
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## 异常类型参考
|
|
456
|
+
|
|
457
|
+
| 异常类 | 含义 | 常见触发场景 |
|
|
458
|
+
|--------|------|------------|
|
|
459
|
+
| `AuthError` | 基类 | — |
|
|
460
|
+
| `NotAuthenticatedError` | 未登录 | 未执行 login 就调用 get_token |
|
|
461
|
+
| `SystemNotFoundError` | 系统别名不存在 | `-s` 参数传了未注册的别名 |
|
|
462
|
+
| `DeviceFlowExpiredError` | 授权码超时 | 300s 内未在浏览器完成授权 |
|
|
463
|
+
| `DeviceFlowDeniedError` | 用户拒绝授权 | 浏览器点击"拒绝" |
|
|
464
|
+
| `TokenRefreshError` | 刷新失败 | 网络异常或 session 失效 |
|
|
465
|
+
| `StorageError` | 凭证存储异常 | Keychain 和文件存储均失败 |
|
|
466
|
+
| `NetworkError` | 网络连接异常 | 无法访问后端服务 |
|