Skip to main content

NOC — 多云运维 ops CLI

用自然语言运维多云机群(AWS / 阿里云 / 腾讯云 / 火山引擎 / Google Cloud / Azure / Oracle,另只读纳管 Cloudflare / Supabase)的 ops CLI:核心只用 Python 标准库,负责清单同步、运维看板、定时重启、读写闸门;agent 入口是一份 skill(pholex/multicloud-ops),装进 Claude Code / Codex / Cursor / Gemini CLI / Kiro / Cline 等任何带 shell 的 agent 客户端即可用,模型由客户端自带。 可选组件:[mcp] 给没有 shell 的 GUI 客户端(Claude Desktop)接 MCP。终端内的自然语言入口 ops "<指令>" 不在公开包里,由扩展包经 entry point noc_ops.default_command 提供。各入口共享 providers + sync + aws_safety + schedule_ops 这套底座。 能力随日常运维不断沉淀:每做一项新运维,就存成一个 runbook,攒一段时间后接管大部分日常工作。

代码与工作区(分离)

代码(pip/uv 装进 venv,只读):

src/noc_ops/
├── cli.py            # `ops` 入口:分发 sync/noc/doctor/setup,默认走 agent
├── sync.py           # 扫实例/域名/RDS/S3/Lambda/CloudFront/IAM/AI 密钥(Bedrock key)/SQS·SNS·SES·EventBridge/成本/账务额度,生成 inventory+data.json+ssh config
├── mcp_server.py     # MCP server(`ops-mcp` 入口,给 Codex 等)
├── schedule_ops.py   # 计划任务(定时重启,EventBridge + Lambda 派发)
├── aws_safety.py     # 读/写操作分类器(权限闸门)
├── ops_log.py        # 操作日志(写操作审计流水)
├── paths.py          # 工作区路径解析(代码↔数据分离)
├── doctor.py / setup_clients.py   # 体检 / 多客户端一键安装
├── providers/        # 多云驱动:base + aws/aliyun/tencent/volcengine/gcp/azure/oracle/cloudflare/supabase/synology/vmware/sangfor/local
├── dashboard/        # 看板前端(server.py + index.html + 自托管 ag-Grid/字体)
├── skill/SKILL.md.tmpl            # Claude Code skill 模板(setup 时渲染安装)
└── assets/runbooks/  # 全新安装的种子 runbook

工作区(可变数据,默认 ~/.noc,可用 NOC_HOME 或 ops setup --workspace 指定):

<workspace>/
├── inventory.md      # 实例+域名+账务额度清单(人读,sync 生成)
├── data.json         # 机读数据(sync 生成,看板/MCP 用)
├── runbooks/*.md     # 能力库(用户沉淀,随用增长;升级不丢)
└── .state/           # 运行时状态(ssh 用户缓存 / 快照 / 操作日志)

安装与运行

支持 macOS / Linux(纯 Python 包)。一行装(推荐):curl -fsSL https://<host>/install.sh | sh(自动装 uv + 从 PyPI 装 + 接入客户端)。或手动:

uv tool install noc-ops                     # 或 pipx install noc-ops;开发者:uv tool install <本仓路径>
uv tool install --force 'noc-ops[mcp]'      # 可选:ops-mcp,仅无 shell 的 GUI 客户端(Claude Desktop)需要
ops setup [--workspace ~/Developer/noc]    # 记工作区 + 经 `skills` CLI 把 skill 扇出到所有已装客户端(skill 优先)
ops init                                    # 交互式生成配置(发现账号/区域/SSH key,免手编 TOML)
ops doctor --fix                            # 体检:云 CLI 依赖 / 凭证 / 工作区 / 客户端;--fix 自动修

ops "宁夏有几台 EC2 在运行"                 # 一次性指令(任意目录可跑)
ops                                         # 进入交互模式(推荐:边做边沉淀)
ops sync                                    # 同步实例清单 + SSH 配置(新增实例后跑)
ops sync --account=<账号>                   # 只刷某一个云账号(AWS 账号 ID / 阿里云 profile 名)
ops noc                                     # 启动 NOC 运维看板(默认后台;status/stop/restart 管理)

前置:用到哪朵云就装好对应 CLI 并配好凭证(aws / aliyun / tccli / ve / gcloud / az / oci;ops doctor 会逐项检查,没装 CLI 的云 ops sync 自动跳过)。 渠道 skill 优先;无 shell 的 GUI 客户端(如 Claude Desktop)才需 ops setup --with-mcp(外包 npx add-mcp,含 Claude Desktop)。

ops noc — NOC 运维看板

ops noc 启动本地服务(默认 http://127.0.0.1:8765),用 ag-Grid(社区版,MIT)密集表格 呈现全部实例:状态灯、账号、区域(旗帜)、类型、IP、实例 ID(点击复制)、登录用户、直连/跳板/SSM(无密钥对的 AWS 实例视为仅 SSM Session Manager 可达,不配 SSH)。 顶部标签页分类展示 实例 / 域名 / 数据库 / 存储 / 函数 / CDN / IAM / AI 密钥 / 消息·事件 / 成本 / 计划任务 / 剧本 / 操作日志 十三类;「剧本」页列出 runbooks/ 全部剧本(标题/沉淀时间/是否写操作/触发意图),点剧本名即在新页打开其 markdown(/runbook?name=<名>,限定在 runbooks 目录内)。 支持按账号/区域/状态筛选、关键字搜索、点表头排序、列宽拖拽/重排、每列筛选菜单、导出 CSV。 Quartz 主题跟随系统明暗。右上「刷新」触发一次 ops sync(重扫 AWS + 探测新机器)再重载。 数据来自 <workspace>/data.json(由 ops sync 生成)。

账号级的账务/额度(credits 键:信用余额、免费额度到期、超额保护、预算告警)没有独立 tab——它是账号状态而非资源清单,渲染在 inventory.md 的「💳 云账务 / 额度」节,刷新用 ops sync --kind=credits。与「成本」tab 的分工:credits 是「还剩多少、超额会怎样」,billing 是「花了多少」的流水。

「AI 密钥」tab 只盘点元数据(限定到哪个 API、绑定的服务账号、客户端限制、创建时间),永远不取密钥串(不调 get-key-string,data.json / inventory 里不会出现 key 本体)。目前接了两朵云:GCP 的 Cloud API Keys(AI Studio 的 Gemini key 与 Vertex AI Express key 本质都是它,按 apiTargets 标成「Gemini API」/「Vertex AI」,只盘 AI 用途;无限制 key 标红,Google 已在封禁闲置的无限制 key;项目需启用 apikeys.googleapis.com)和 AWS 的 Bedrock 长期 API key(IAM 服务专用凭证,含 Claude Platform on AWS key;只盘全球区(--all-users 一次列全;中国区不支持该参数,直接跳过);短期 12h key 本地签出、不可列)。阿里云百炼 key 没有列表 OpenAPI,暂未纳管。刷新 ops sync --kind=apikeys。

ag-Grid 的 JS、Inter 字体均本地自托管在 src/noc_ops/dashboard/vendor/、不走第三方 CDN(遵全局规则); 看板服务用 Python stdlib 起、运行期不拉外部包。 (注:这里说的是「看板运行期」的取舍——不是全工程教条。ops setup 装 skill 时会按需调用 skills CLI(npx skills,节点级工具)做多客户端扇出;用对的成熟工具优先于死守零依赖。)

生命周期:ops noc 默认后台守护启动(detach,关终端不死,日志写 <workspace>/.state/noc.log),立即返回。

  • ops noc status — 看在不在跑(PID / URL)
  • ops noc stop — 停掉(只杀 noc 自己的监听进程,非 noc 占用仅告警)
  • ops noc restart — 停旧启新
  • ops noc -f — 前台跑(占终端、Ctrl+C 退出,调试用)

选项:ops noc --port 9000 --no-open(可与上面组合)。

ops sync — 实例清单/SSH 配置同步

新增或变更 EC2 后跑 ops sync,它会全量扫描、对比快照、报告 新增/变更/删除,并重新生成 inventory.md 与 ~/.ssh/config(marker 段)。私钥按约定 ~/.ssh/<profile>/<KeyName>.pem 自动推导;登录用户名(ec2-user / ubuntu / centos)对未缓存实例自动探测一次并缓存(幂等,日常只探新机器)。

不必每次都全量重扫,可按两个维度收窄(都是 patch 式合并写回 data.json,不整份覆盖):

ops sync --kind=instances                          # 按资源类型收窄(看板「按 tab 单刷」),扫所有账号
ops sync --account=123456789012                    # 按 AWS 账号收窄:只扫该账号(~25s vs 全量一两分钟)
ops sync --account=123456789012 --kind=instances   # 两者组合:只刷该账号的实例(~3s)
ops sync --account=<aliyun-profile>                          # 阿里云账号也认(profile 名或账号 ID,~2s)
ops sync --probe=<实例名|ID>                       # 只探这一台 AWS 实例的 SSH 登录用户名并回写 config(零云 API,几秒)

--account= 只重扫指定账号,同云其它账号 / 其它云的行原样沿用;~/.ssh/config 的托管段虽是整段 重写,但沿用账号的 Host 会一并还原写回(产出与全账号刷新逐字节一致)。inventory.md 与实例快照 是全量产物、两条收窄路径都不动它们。

账号名按云解析:AWS 用账号 ID,阿里云用 CLI profile 名(如 <profile>)或账号 ID 都行。 各云能按账号刷的资源类型不同(AWS 九类;阿里云 = 实例/存储/域名,即 provider 真会产出的), 点名了该云没有的类型会直接拒绝并列出可用值。

非公网机器(VMware / Sangfor HCI / 群晖 / 本地物理机)不参与全量 sync(连不上时不该被误判 "已删除"),按网络域分两条命令单刷,各有各的门控,互不覆盖:

ops sync --local        # 只刷内网机器(network=lan);门控 = local_net.probe 内网探针
ops sync --tailscale    # 只刷 Tailscale 组网上的机器;门控 = `tailscale status`
ops sync --index        # 只刷 runbooks/操作日志索引进 data.json(零网络,秒级)

网络域按端点地址自动推导(100.64.0.0/10 或 *.ts.net → tailscale,其余 → lan), 账号里显式写 network = "tailscale" 可覆盖。两个域故意不合并——"连不上"的含义不同: 内网看人在不在内网,Tailscale 看 tailscaled 跑没跑、对端节点是否 Online。详见 runbooks/sync-inventory.md 与 src/noc_ops/netprobe.py。 账号在 src/noc_ops/providers/aws.py 的 ACCOUNTS 维护;别名前缀/跳板在 src/noc_ops/sync.py 的 ALIAS_PREFIX/JUMPS。详见 runbooks/sync-inventory.md。

可选环境变量:OPS_MODEL(默认 claude-sonnet-4-6)。

ops reboot — 重启一台实例(公有云 + 本地 HCI 同一入口)

ops reboot <实例名|ID>            # 重启:按 cloud 自动选通道
ops reboot <实例名|ID> --status   # 只查实时状态(只读),重启后隔 ~40 秒用它复查
ops reboot <实例名|ID> --dry-run  # 只打印将要执行的命令

通道按 cloud 走 Provider.reboot_argv:AWS aws ec2 reboot-instances、腾讯 RebootInstances、 阿里 RebootInstance、火山 ecs RebootInstance(优雅)、GCP instances reset(硬)、Azure vm restart、Oracle SOFTRESET, VMware 走 vCenter REST、深信服 HCI 走 SCP 管控 API(两者都是 Token 认证 + Keychain 取密码, CLI 拼不出来——这也是本命令存在的理由:以前只有 MCP server 接了这条通道,走 skill 的 Claude Code / Codex 够不着)。群晖 / ESXi 宿主 / Cloudflare / Supabase 没有管控 API, 会如实拒绝并给出该走哪条路(DSM、SSH 别名、控制台),不抛异常。

⚠️ 深信服目前只有 --status 可用:这版 SCP 不认现有重启端点(实测 404),命令会如实报错 并指向替代路径(Linux 走 SSH、Windows 去控制台)。端点考古与下一步见「待办」。

目标解析由严到宽:精确 ID → 精确名 → 忽略大小写 → 唯一子串;匹配到多台一律列出来让你挑 (srv07/srv08、泛微OA 应用/数据库 这类同前缀名太多,猜错就是重启错生产机)。 重启属低风险可逆,按安全模型免二次确认直接执行,并自动记一条操作日志(--source 声明调用方)。

安全模型

操作类型 行为
只读(describe/list/get、df/状态查询等) 自动执行,不打扰
实例重启(ops reboot、各云 reboot API) 自动执行,低风险可逆;自动记审计日志
其它写操作(启停/销毁/改配置、远程改动、写文件) 先弹确认,y 才执行

分类逻辑在 src/noc_ops/aws_safety.py,保守原则:拿不准一律当写操作、要确认。

⚠️ 关键实现点:写操作工具不能放进 ClaudeAgentOptions.allowed_tools——那会被 SDK 自动批准、绕过确认回调。只有纯只读内置工具(Read/Glob/Grep)放 allowed_tools,其余都走 can_use_tool 闸门。

怎么加一项新能力(沉淀 runbook)

  1. 在交互模式里和 Agent 一起把某项运维做完。
  2. Agent 会主动问要不要沉淀;同意后它按 _TEMPLATE.md 在 runbooks/ 生成剧本。
  3. 下次遇到同类需求,Agent 会先 Glob 到这个剧本、照着执行。

加能力 ≈ 写一个 markdown,不用改代码。

开发 / 测试

改本仓代码时的约定(代码与工作区分离、改完必须重装、同步清单、提交规范)见 CLAUDE.md,这里只列最常用的三条。

测试

uv run --extra dev pytest -m unit -q     # Tier 1:离线、零 LLM、秒级,改完就跑

公开仓只有离线单元测试(Tier 1)。单测读的是匿名化夹具 tests/fixtures/workspace/ops-config.toml,不读任何真实工作区。

改完 src/ 要重装全局 ops:全局 ops 是 uv tool 装的 wheel 拷贝,不跟随 src/。uv tool install --force --no-cache <本仓路径>,否则「代码改好了、跑起来还是旧行为」。

新增 provider / 资源种类 / 看板 tab 的同步清单:providers/<cloud>.py + sync.py → dashboard/index.html → skill/SKILL.md.tmpl(公开 skill 仓 pholex/multicloud-ops 同步)→ 本 README → ops setup 重扇出 skill 再重装。漏一处就出现「看板有、agent 不知道」。

数据文件不入库:仓根目录同时就是工作区,data.json / inventory.md / .state/ / local-servers.toml / ops-config.toml / runbooks/ 都是工作区数据,已在 .gitignore。秘密(token / PAT / 密码)走系统 Keychain 或 Parameter Store,不进仓库、也不进 ops-config.toml。

插件子命令(entry point)

公司 / 团队专属的子命令不进公开 wheel,放在自己的私有包里,经 entry point 组 noc_ops.commands 挂回 ops:

# 私有包的 pyproject.toml
[project]
dependencies = ["noc-ops"]
[project.entry-points."noc_ops.commands"]

acme = "acme_ops.skill_fragment:fragment"            # 无参返回 markdown;ops setup 渲染 skill 时拼在末尾

装法:uv tool install 'noc-ops[all]' --with <你的插件包>。ops help 末尾会列出已装的插件命令;内建命令名不可被插件覆盖;插件加载失败只报该命令、不影响 ops 其余功能。插件读自己的配置段用 deploy_config.section("<段名>");插件专属的 agent 使用规则经 noc_ops.skill_fragments 随包提供,ops setup 自动拼进完整版 skill,不必改公开模板。

许可

Apache License 2.0,见 LICENSE 与 NOTICE。看板自托管的第三方前端组件(AG Grid Community / Inter 字体)各随其原许可(MIT / OFL 1.1)。

Metadata

Release files for noc-ops 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for noc-ops 0.1.2
File Interpreter ABI Platform
noc_ops-0.1.2-py3-none-any.whl Python 3 none any Details

Release files / noc_ops-0.1.2-py3-none-any.whl

Download URL noc_ops-0.1.2-py3-none-any.whl
Size 770.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
11991f4e7213468d11b6f795b4f2bcebfd38ea80228a77f13072f603e9875105
BLAKE2b-256 checksum
How to use checksums
8ed284e98877d2292e1612ae795160831fccd4e4d66e63480d9da77b25315fe9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for noc-ops 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page