noc-ops 0.1.0__tar.gz
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.
Potentially problematic release.
This version of noc-ops might be problematic. Click here for more details.
- noc_ops-0.1.0/.gitignore +39 -0
- noc_ops-0.1.0/LICENSE +201 -0
- noc_ops-0.1.0/NOTICE +18 -0
- noc_ops-0.1.0/PKG-INFO +275 -0
- noc_ops-0.1.0/README.md +239 -0
- noc_ops-0.1.0/pyproject.toml +65 -0
- noc_ops-0.1.0/src/noc_ops/__init__.py +2 -0
- noc_ops-0.1.0/src/noc_ops/agent.py +486 -0
- noc_ops-0.1.0/src/noc_ops/assets/ops-config.default.toml +127 -0
- noc_ops-0.1.0/src/noc_ops/assets/runbooks/README.md +18 -0
- noc_ops-0.1.0/src/noc_ops/assets/runbooks/alb-access-log-decommission.md +53 -0
- noc_ops-0.1.0/src/noc_ops/assets/runbooks/certbot-renewal-troubleshooting.md +87 -0
- noc_ops-0.1.0/src/noc_ops/assets/runbooks/ec2-public-exposure-hardening.md +79 -0
- noc_ops-0.1.0/src/noc_ops/assets/runbooks/s3-bucket-usage-check.md +52 -0
- noc_ops-0.1.0/src/noc_ops/assets/runbooks/site-access-source-stats.md +75 -0
- noc_ops-0.1.0/src/noc_ops/aws_safety.py +404 -0
- noc_ops-0.1.0/src/noc_ops/cli.py +213 -0
- noc_ops-0.1.0/src/noc_ops/dashboard/__init__.py +1 -0
- noc_ops-0.1.0/src/noc_ops/dashboard/favicon.svg +4 -0
- noc_ops-0.1.0/src/noc_ops/dashboard/index.html +1091 -0
- noc_ops-0.1.0/src/noc_ops/dashboard/server.py +483 -0
- noc_ops-0.1.0/src/noc_ops/dashboard/vendor/ag-grid-community.min.js +14024 -0
- noc_ops-0.1.0/src/noc_ops/dashboard/vendor/fonts/inter-latin-wght-normal.woff2 +0 -0
- noc_ops-0.1.0/src/noc_ops/deploy_config.py +264 -0
- noc_ops-0.1.0/src/noc_ops/doctor.py +141 -0
- noc_ops-0.1.0/src/noc_ops/egress_probe.py +535 -0
- noc_ops-0.1.0/src/noc_ops/error_patterns.py +200 -0
- noc_ops-0.1.0/src/noc_ops/init_wizard.py +259 -0
- noc_ops-0.1.0/src/noc_ops/license.py +305 -0
- noc_ops-0.1.0/src/noc_ops/mcp_server.py +397 -0
- noc_ops-0.1.0/src/noc_ops/netprobe.py +183 -0
- noc_ops-0.1.0/src/noc_ops/ops_log.py +145 -0
- noc_ops-0.1.0/src/noc_ops/paths.py +110 -0
- noc_ops-0.1.0/src/noc_ops/providers/__init__.py +25 -0
- noc_ops-0.1.0/src/noc_ops/providers/aliyun.py +279 -0
- noc_ops-0.1.0/src/noc_ops/providers/aws.py +455 -0
- noc_ops-0.1.0/src/noc_ops/providers/azure.py +359 -0
- noc_ops-0.1.0/src/noc_ops/providers/base.py +122 -0
- noc_ops-0.1.0/src/noc_ops/providers/cloudflare.py +81 -0
- noc_ops-0.1.0/src/noc_ops/providers/gcp.py +365 -0
- noc_ops-0.1.0/src/noc_ops/providers/local.py +131 -0
- noc_ops-0.1.0/src/noc_ops/providers/oracle.py +290 -0
- noc_ops-0.1.0/src/noc_ops/providers/sangfor.py +396 -0
- noc_ops-0.1.0/src/noc_ops/providers/supabase.py +88 -0
- noc_ops-0.1.0/src/noc_ops/providers/synology.py +201 -0
- noc_ops-0.1.0/src/noc_ops/providers/tencent.py +184 -0
- noc_ops-0.1.0/src/noc_ops/providers/vmware.py +291 -0
- noc_ops-0.1.0/src/noc_ops/providers/volcengine.py +319 -0
- noc_ops-0.1.0/src/noc_ops/reboot_cli.py +197 -0
- noc_ops-0.1.0/src/noc_ops/schedule_ops.py +218 -0
- noc_ops-0.1.0/src/noc_ops/setup_clients.py +216 -0
- noc_ops-0.1.0/src/noc_ops/skill/SKILL.md.tmpl +63 -0
- noc_ops-0.1.0/src/noc_ops/sync.py +1572 -0
noc_ops-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 工作区运行时数据(sync 生成的看板数据 + 状态/快照/日志,含 IP/账号/命令,勿外泄)
|
|
2
|
+
/data.json
|
|
3
|
+
/local-servers.toml
|
|
4
|
+
/.state/
|
|
5
|
+
|
|
6
|
+
# 本地 Claude Code 设置(机器本地,不入库)
|
|
7
|
+
.claude/settings.local.json
|
|
8
|
+
|
|
9
|
+
# Python 打包/缓存
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.pyc
|
|
12
|
+
.venv/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
build/
|
|
15
|
+
dist/
|
|
16
|
+
|
|
17
|
+
# macOS
|
|
18
|
+
.DS_Store
|
|
19
|
+
|
|
20
|
+
# 混淆分发构建产物(PyArmor,由 scripts/build-obfuscated.sh 生成)
|
|
21
|
+
/build_obf/
|
|
22
|
+
|
|
23
|
+
# 测试夹具工作区:只保留匿名化的 ops-config.toml,其余运行时产物不入库
|
|
24
|
+
/tests/fixtures/workspace/.state/
|
|
25
|
+
/tests/fixtures/workspace/runbooks/
|
|
26
|
+
/tests/fixtures/workspace/data.json
|
|
27
|
+
/tests/fixtures/workspace/inventory.md
|
|
28
|
+
/tests/fixtures/workspace/local-servers.toml
|
|
29
|
+
|
|
30
|
+
# 工作区本体(仓根目录=作者的真实工作区):部署配置 / 清单 / 剧本都是机器特定数据,不入库
|
|
31
|
+
# 2026-10-25 起停止跟踪(此前被跟踪过,公开本仓前须 orphan 新仓重建历史)
|
|
32
|
+
/ops-config.toml
|
|
33
|
+
/inventory.md
|
|
34
|
+
/runbooks/
|
|
35
|
+
# 本机 Claude Code 项目级 MCP 配置与渠道能力目录(含个人路径)
|
|
36
|
+
/.mcp.json
|
|
37
|
+
/capabilities.toml
|
|
38
|
+
# 无关的飞书文档草稿缓存
|
|
39
|
+
/draft_*_folder/
|
noc_ops-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
noc_ops-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
noc-ops — 多云运维 ops CLI
|
|
2
|
+
Copyright 2026 Fenghuang
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
|
|
16
|
+
Bundled third-party components (src/noc_ops/dashboard/vendor/):
|
|
17
|
+
- AG Grid Community — MIT License, Copyright (c) AG Grid Ltd
|
|
18
|
+
- Inter font — SIL Open Font License 1.1, Copyright (c) The Inter Project Authors
|
noc_ops-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: noc-ops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 多云运维 ops CLI —— 9 朵云(AWS / 阿里云 / 腾讯云 / 火山引擎 / GCP / Azure / Oracle / Cloudflare / Supabase)+ 本地网络机器:清单同步、运维看板、定时重启、Claude Code / Codex skill;可选自然语言 agent 与 MCP
|
|
5
|
+
Project-URL: Homepage, https://github.com/pholex/noc-ops
|
|
6
|
+
Project-URL: Repository, https://github.com/pholex/noc-ops
|
|
7
|
+
Project-URL: Skill, https://github.com/pholex/multicloud-ops
|
|
8
|
+
Author: Fenghuang
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
License-File: NOTICE
|
|
12
|
+
Keywords: aliyun,aws,azure,claude-code,devops,gcp,multicloud,noc,oci,ops,skill,tencent-cloud
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Topic :: System :: Systems Administration
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Provides-Extra: agent
|
|
22
|
+
Requires-Dist: claude-agent-sdk<0.3,>=0.2.156; extra == 'agent'
|
|
23
|
+
Provides-Extra: all
|
|
24
|
+
Requires-Dist: claude-agent-sdk<0.3,>=0.2.156; extra == 'all'
|
|
25
|
+
Requires-Dist: mcp<3,>=2.2.0; extra == 'all'
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: claude-agent-sdk<0.3,>=0.2.156; extra == 'dev'
|
|
28
|
+
Requires-Dist: mcp<3,>=2.2.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
30
|
+
Requires-Dist: pyyaml; extra == 'dev'
|
|
31
|
+
Provides-Extra: mcp
|
|
32
|
+
Requires-Dist: mcp<3,>=2.2.0; extra == 'mcp'
|
|
33
|
+
Provides-Extra: sangfor
|
|
34
|
+
Requires-Dist: pycryptodome; extra == 'sangfor'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# NOC — 多云运维 ops CLI
|
|
38
|
+
|
|
39
|
+
用自然语言指令运维多云机群(AWS / 阿里云 / 腾讯云 / 火山引擎 / Google Cloud / Azure / Oracle,另只读纳管 Cloudflare / Supabase)的 `ops` CLI,基于 [Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk/python)。
|
|
40
|
+
一次安装就接好多个 LLM 客户端:**`ops` CLI 本体 + Claude Code skill + Codex MCP**,共享 `providers + sync + aws_safety + schedule_ops` 这套底座。
|
|
41
|
+
能力随日常运维不断**沉淀**:每做一项新运维,就存成一个 runbook,攒一段时间后接管大部分日常工作。
|
|
42
|
+
|
|
43
|
+
## 代码与工作区(分离)
|
|
44
|
+
|
|
45
|
+
**代码**(pip/uv 装进 venv,只读):
|
|
46
|
+
```
|
|
47
|
+
src/noc_ops/
|
|
48
|
+
├── cli.py # `ops` 入口:分发 sync/noc/doctor/setup,默认走 agent
|
|
49
|
+
├── agent.py # 自然语言 agent(交互/一次性两种模式)
|
|
50
|
+
├── sync.py # 扫实例/域名/RDS/S3/Lambda/CloudFront/IAM/AI 密钥(Bedrock key)/SQS·SNS·SES·EventBridge/成本/账务额度,生成 inventory+data.json+ssh config
|
|
51
|
+
├── mcp_server.py # MCP server(`ops-mcp` 入口,给 Codex 等)
|
|
52
|
+
├── schedule_ops.py # 计划任务(定时重启,EventBridge + Lambda 派发)
|
|
53
|
+
├── aws_safety.py # 读/写操作分类器(权限闸门)
|
|
54
|
+
├── ops_log.py # 操作日志(写操作审计流水)
|
|
55
|
+
├── paths.py # 工作区路径解析(代码↔数据分离)
|
|
56
|
+
├── doctor.py / setup_clients.py # 体检 / 多客户端一键安装
|
|
57
|
+
├── providers/ # 多云驱动:base + aws/aliyun/tencent/volcengine/gcp/azure/oracle/cloudflare/supabase/synology/vmware/sangfor/local
|
|
58
|
+
├── dashboard/ # 看板前端(server.py + index.html + 自托管 ag-Grid/字体)
|
|
59
|
+
├── skill/SKILL.md.tmpl # Claude Code skill 模板(setup 时渲染安装)
|
|
60
|
+
└── assets/runbooks/ # 全新安装的种子 runbook
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**工作区**(可变数据,默认 `~/.noc`,可用 `NOC_HOME` 或 `ops setup --workspace` 指定):
|
|
64
|
+
```
|
|
65
|
+
<workspace>/
|
|
66
|
+
├── inventory.md # 实例+域名+账务额度清单(人读,sync 生成)
|
|
67
|
+
├── data.json # 机读数据(sync 生成,看板/MCP 用)
|
|
68
|
+
├── runbooks/*.md # 能力库(用户沉淀,随用增长;升级不丢)
|
|
69
|
+
└── .state/ # 运行时状态(ssh 用户缓存 / 快照 / 操作日志)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 安装与运行
|
|
73
|
+
|
|
74
|
+
支持 macOS / Linux(纯 Python 包)。一行装(推荐):`curl -fsSL https://<host>/install.sh | sh`(自动装 uv + 从 PyPI 装 + 接入客户端)。或手动:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
uv tool install noc-ops # 或 pipx install noc-ops;开发者:uv tool install <本仓路径>
|
|
78
|
+
uv tool install --force 'noc-ops[agent]' # 可选:终端自然语言 agent(需 ANTHROPIC_API_KEY)
|
|
79
|
+
uv tool install --force 'noc-ops[mcp]' # 可选:ops-mcp,仅无 shell 的 GUI 客户端(Claude Desktop)需要
|
|
80
|
+
ops setup [--workspace ~/Developer/noc] # 记工作区 + 经 `skills` CLI 把 skill 扇出到所有已装客户端(skill 优先)
|
|
81
|
+
ops init # 交互式生成配置(发现账号/区域/SSH key,免手编 TOML)
|
|
82
|
+
ops doctor --fix # 体检:云 CLI 依赖 / 凭证 / 工作区 / 客户端;--fix 自动修
|
|
83
|
+
|
|
84
|
+
ops "宁夏有几台 EC2 在运行" # 一次性指令(任意目录可跑)
|
|
85
|
+
ops # 进入交互模式(推荐:边做边沉淀)
|
|
86
|
+
ops sync # 同步实例清单 + SSH 配置(新增实例后跑)
|
|
87
|
+
ops sync --account=<账号> # 只刷某一个云账号(AWS 账号 ID / 阿里云 profile 名)
|
|
88
|
+
ops noc # 启动 NOC 运维看板(默认后台;status/stop/restart 管理)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
前置:用到哪朵云就装好对应 CLI 并配好凭证(`aws` / `aliyun` / `tccli` / `ve` / `gcloud` / `az` / `oci`;`ops doctor` 会逐项检查,没装 CLI 的云 `ops sync` 自动跳过)。
|
|
92
|
+
渠道 **skill 优先**;无 shell 的 GUI 客户端(如 Claude Desktop)才需 `ops setup --with-mcp`(外包 `npx add-mcp`,含 Claude Desktop)。
|
|
93
|
+
|
|
94
|
+
## ops noc — NOC 运维看板
|
|
95
|
+
|
|
96
|
+
`ops noc` 启动本地服务(默认 `http://127.0.0.1:8765`),用 **ag-Grid**(社区版,MIT)密集表格
|
|
97
|
+
呈现全部实例:状态灯、账号、区域(旗帜)、类型、IP、实例 ID(点击复制)、登录用户、直连/跳板/SSM(无密钥对的 AWS 实例视为仅 SSM Session Manager 可达,不配 SSH)。
|
|
98
|
+
顶部标签页分类展示 **实例 / 域名 / 数据库 / 存储 / 函数 / CDN / IAM / AI 密钥 / 消息·事件 / 成本 / 计划任务 / 剧本 / 操作日志** 十三类;「剧本」页列出 `runbooks/` 全部剧本(标题/沉淀时间/是否写操作/触发意图),点剧本名即在新页打开其 markdown(`/runbook?name=<名>`,限定在 runbooks 目录内)。
|
|
99
|
+
支持按账号/区域/状态筛选、关键字搜索、点表头排序、列宽拖拽/重排、每列筛选菜单、**导出 CSV**。
|
|
100
|
+
Quartz 主题跟随系统明暗。右上「刷新」触发一次 `ops sync`(重扫 AWS + 探测新机器)再重载。
|
|
101
|
+
数据来自 `<workspace>/data.json`(由 `ops sync` 生成)。
|
|
102
|
+
|
|
103
|
+
> 账号级的**账务/额度**(`credits` 键:信用余额、免费额度到期、超额保护、预算告警)没有独立 tab——它是账号状态而非资源清单,渲染在 `inventory.md` 的「💳 云账务 / 额度」节,刷新用 `ops sync --kind=credits`。与「成本」tab 的分工:credits 是「还剩多少、超额会怎样」,billing 是「花了多少」的流水。
|
|
104
|
+
|
|
105
|
+
> 「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`。
|
|
106
|
+
|
|
107
|
+
ag-Grid 的 JS、Inter 字体均**本地自托管在 `src/noc_ops/dashboard/vendor/`、不走第三方 CDN**(遵全局规则);
|
|
108
|
+
看板服务用 Python stdlib 起、运行期不拉外部包。
|
|
109
|
+
(注:这里说的是「看板运行期」的取舍——不是全工程教条。`ops setup` 装 skill 时会按需调用
|
|
110
|
+
`skills` CLI(`npx skills`,节点级工具)做多客户端扇出;用对的成熟工具优先于死守零依赖。)
|
|
111
|
+
|
|
112
|
+
**生命周期**:`ops noc` **默认后台守护启动**(detach,关终端不死,日志写 `<workspace>/.state/noc.log`),立即返回。
|
|
113
|
+
- `ops noc status` — 看在不在跑(PID / URL)
|
|
114
|
+
- `ops noc stop` — 停掉(只杀 noc 自己的监听进程,非 noc 占用仅告警)
|
|
115
|
+
- `ops noc restart` — 停旧启新
|
|
116
|
+
- `ops noc -f` — 前台跑(占终端、Ctrl+C 退出,调试用)
|
|
117
|
+
|
|
118
|
+
选项:`ops noc --port 9000 --no-open`(可与上面组合)。
|
|
119
|
+
|
|
120
|
+
## ops sync — 实例清单/SSH 配置同步
|
|
121
|
+
|
|
122
|
+
新增或变更 EC2 后跑 `ops sync`,它会全量扫描、对比快照、报告 新增/变更/删除,并重新生成
|
|
123
|
+
`inventory.md` 与 `~/.ssh/config`(marker 段)。私钥按约定 `~/.ssh/<profile>/<KeyName>.pem`
|
|
124
|
+
自动推导;登录用户名(ec2-user / ubuntu / centos)对未缓存实例自动探测一次并缓存(幂等,日常只探新机器)。
|
|
125
|
+
|
|
126
|
+
不必每次都全量重扫,可按两个维度收窄(都是 patch 式合并写回 `data.json`,不整份覆盖):
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
ops sync --kind=instances # 按资源类型收窄(看板「按 tab 单刷」),扫所有账号
|
|
130
|
+
ops sync --account=123456789012 # 按 AWS 账号收窄:只扫该账号(~25s vs 全量一两分钟)
|
|
131
|
+
ops sync --account=123456789012 --kind=instances # 两者组合:只刷该账号的实例(~3s)
|
|
132
|
+
ops sync --account=<aliyun-profile> # 阿里云账号也认(profile 名或账号 ID,~2s)
|
|
133
|
+
ops sync --probe=<实例名|ID> # 只探这一台 AWS 实例的 SSH 登录用户名并回写 config(零云 API,几秒)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`--account=` 只重扫指定账号,同云其它账号 / 其它云的行原样沿用;`~/.ssh/config` 的托管段虽是整段
|
|
137
|
+
重写,但沿用账号的 Host 会一并还原写回(产出与全账号刷新逐字节一致)。`inventory.md` 与实例快照
|
|
138
|
+
是全量产物、两条收窄路径都不动它们。
|
|
139
|
+
|
|
140
|
+
账号名按云解析:**AWS** 用账号 ID,**阿里云**用 CLI profile 名(如 `<profile>`)或账号 ID 都行。
|
|
141
|
+
各云能按账号刷的资源类型不同(AWS 九类;阿里云 = 实例/存储/域名,即 provider 真会产出的),
|
|
142
|
+
点名了该云没有的类型会直接拒绝并列出可用值。
|
|
143
|
+
|
|
144
|
+
非公网机器(VMware / Sangfor HCI / 群晖 / 本地物理机)**不参与全量 sync**(连不上时不该被误判
|
|
145
|
+
"已删除"),按**网络域**分两条命令单刷,各有各的门控,互不覆盖:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
ops sync --local # 只刷内网机器(network=lan);门控 = local_net.probe 内网探针
|
|
149
|
+
ops sync --tailscale # 只刷 Tailscale 组网上的机器;门控 = `tailscale status`
|
|
150
|
+
ops sync --index # 只刷 runbooks/操作日志索引进 data.json(零网络,秒级)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
网络域按端点地址自动推导(`100.64.0.0/10` 或 `*.ts.net` → tailscale,其余 → lan),
|
|
154
|
+
账号里显式写 `network = "tailscale"` 可覆盖。两个域**故意不合并**——"连不上"的含义不同:
|
|
155
|
+
内网看人在不在内网,Tailscale 看 tailscaled 跑没跑、对端节点是否 Online。详见
|
|
156
|
+
`runbooks/sync-inventory.md` 与 `src/noc_ops/netprobe.py`。
|
|
157
|
+
账号在 `src/noc_ops/providers/aws.py` 的 `ACCOUNTS` 维护;别名前缀/跳板在 `src/noc_ops/sync.py` 的 `ALIAS_PREFIX`/`JUMPS`。详见 `runbooks/sync-inventory.md`。
|
|
158
|
+
|
|
159
|
+
可选环境变量:`OPS_MODEL`(默认 `claude-sonnet-4-6`)。
|
|
160
|
+
|
|
161
|
+
## ops reboot — 重启一台实例(公有云 + 本地 HCI 同一入口)
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
ops reboot <实例名|ID> # 重启:按 cloud 自动选通道
|
|
165
|
+
ops reboot <实例名|ID> --status # 只查实时状态(只读),重启后隔 ~40 秒用它复查
|
|
166
|
+
ops reboot <实例名|ID> --dry-run # 只打印将要执行的命令
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
通道按 `cloud` 走 `Provider.reboot_argv`:AWS `aws ec2 reboot-instances`、腾讯 `RebootInstances`、
|
|
170
|
+
阿里 `RebootInstance`、火山 `ecs RebootInstance`(优雅)、GCP `instances reset`(硬)、Azure `vm restart`、Oracle `SOFTRESET`,
|
|
171
|
+
**VMware 走 vCenter REST、深信服 HCI 走 SCP 管控 API**(两者都是 Token 认证 + Keychain 取密码,
|
|
172
|
+
CLI 拼不出来——这也是本命令存在的理由:以前只有 MCP server 接了这条通道,走 skill 的
|
|
173
|
+
Claude Code / Codex 够不着)。群晖 / ESXi 宿主 / Cloudflare / Supabase 没有管控 API,
|
|
174
|
+
会**如实拒绝并给出该走哪条路**(DSM、SSH 别名、控制台),不抛异常。
|
|
175
|
+
|
|
176
|
+
> ⚠️ **深信服目前只有 `--status` 可用**:这版 SCP 不认现有重启端点(实测 404),命令会如实报错
|
|
177
|
+
> 并指向替代路径(Linux 走 SSH、Windows 去控制台)。端点考古与下一步见「待办」。
|
|
178
|
+
|
|
179
|
+
目标解析由严到宽:精确 ID → 精确名 → 忽略大小写 → 唯一子串;**匹配到多台一律列出来让你挑**
|
|
180
|
+
(`srv07/srv08`、`泛微OA 应用/数据库` 这类同前缀名太多,猜错就是重启错生产机)。
|
|
181
|
+
重启属低风险可逆,按安全模型**免二次确认**直接执行,并自动记一条操作日志(`--source` 声明调用方)。
|
|
182
|
+
|
|
183
|
+
## 安全模型
|
|
184
|
+
|
|
185
|
+
| 操作类型 | 行为 |
|
|
186
|
+
|---|---|
|
|
187
|
+
| 只读(describe/list/get、df/状态查询等) | **自动执行**,不打扰 |
|
|
188
|
+
| 实例重启(`ops reboot`、各云 reboot API) | **自动执行**,低风险可逆;自动记审计日志 |
|
|
189
|
+
| 其它写操作(启停/销毁/改配置、远程改动、写文件) | **先弹确认**,y 才执行 |
|
|
190
|
+
|
|
191
|
+
分类逻辑在 `src/noc_ops/aws_safety.py`,保守原则:**拿不准一律当写操作、要确认**。
|
|
192
|
+
|
|
193
|
+
> ⚠️ 关键实现点:写操作工具**不能**放进 `ClaudeAgentOptions.allowed_tools`——那会被 SDK 自动批准、绕过确认回调。只有纯只读内置工具(Read/Glob/Grep)放 allowed_tools,其余都走 `can_use_tool` 闸门。
|
|
194
|
+
|
|
195
|
+
## 怎么加一项新能力(沉淀 runbook)
|
|
196
|
+
|
|
197
|
+
1. 在交互模式里和 Agent 一起把某项运维做完。
|
|
198
|
+
2. Agent 会主动问要不要沉淀;同意后它按 `_TEMPLATE.md` 在 `runbooks/` 生成剧本。
|
|
199
|
+
3. 下次遇到同类需求,Agent 会先 Glob 到这个剧本、照着执行。
|
|
200
|
+
|
|
201
|
+
**加能力 ≈ 写一个 markdown,不用改代码。**
|
|
202
|
+
|
|
203
|
+
## 开发 / 测试
|
|
204
|
+
|
|
205
|
+
改本仓代码时的约定见 `CLAUDE.md`(给 LLM 客户端读的简版);下面是完整版。
|
|
206
|
+
|
|
207
|
+
### 改完 src/ 必须重装全局 ops
|
|
208
|
+
全局 `ops` 是 `uv tool` 装的 wheel **拷贝**,不跟随 `src/`。改完源码(尤其新增子命令)立刻:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
uv tool install --force --no-cache '<本仓绝对路径>[all]' # [all] 带上 agent+mcp 可选依赖,别把本机 agent 弄丢
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
漏这步的典型症状是「代码明明改好了、跑起来还是旧行为」,排查成本极高。
|
|
215
|
+
|
|
216
|
+
### 测试(两层)
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
uv run --extra dev pytest -m unit -q # Tier 1:离线、零 LLM、秒级,改完就跑
|
|
220
|
+
uv run --extra dev pytest -m eval -q # Tier 2:agent 行为评测,真调 LLM(要 ANTHROPIC_API_KEY,花钱)
|
|
221
|
+
uv run --extra dev pytest -q # 全部(没设 key 时 Tier 2 自动跳过)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
日常只跑 `-m unit`。Tier 2 用 stub 挡住执行层(`agent._run_cli` / `agent._confirm`)+ 冻结的 fixtures 工作区,**绝不碰真云**;细节见 `tests/README.md`。
|
|
225
|
+
|
|
226
|
+
### 新增 provider / 资源种类 / 看板 tab 的同步清单
|
|
227
|
+
这几处必须一起改,漏一处就出现「看板有、agent 不知道」:
|
|
228
|
+
|
|
229
|
+
1. `src/noc_ops/providers/<cloud>.py` + `sync.py` —— 扫出来、并进 `data.json`
|
|
230
|
+
2. `src/noc_ops/dashboard/index.html` —— tab 与列
|
|
231
|
+
3. `src/noc_ops/skill/SKILL.md.tmpl` —— agent 靠它才知道查什么、怎么查(公开 skill 仓 pholex/multicloud-ops 里 `skills/multicloud-ops/SKILL.md` 的云列表同步)
|
|
232
|
+
4. `README.md` —— tab 列表与能力描述
|
|
233
|
+
5. 改完跑 `ops setup` 重扇出 skill,再按上面重装全局 `ops`
|
|
234
|
+
|
|
235
|
+
### 数据文件不入库
|
|
236
|
+
仓根目录同时**就是**当前工作区,所以混着两类东西:`data.json` / `inventory.md` / `.state/` / `local-servers.toml` 都是 `ops sync` 等生成的产物,**不手改、不入库**(已在 `.gitignore`;含 IP/账号/命令,勿外泄)。要改内容,改生成它们的代码。
|
|
237
|
+
真实的 `ops-config.toml` 与 `runbooks/` 同样是工作区数据、不入库;单测读的是匿名化夹具 `tests/fixtures/workspace/ops-config.toml`。
|
|
238
|
+
|
|
239
|
+
秘密(token / PAT / 密码)走 macOS Keychain 或 Parameter Store,**不进仓库、也不进 `ops-config.toml`**。
|
|
240
|
+
|
|
241
|
+
### 分发构建
|
|
242
|
+
分发形态(2026-10-25 定):**skill 免费公开 + CLI 发 PyPI(纯 `py3-none-any`,macOS / Linux)+ 收费只圈 pro 场景**。
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
uv build # dist/noc_ops-<版本>-py3-none-any.whl + sdist
|
|
246
|
+
uv publish # 推 PyPI(token 走环境变量 UV_PUBLISH_TOKEN,不进仓库)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
发布前在干净环境过一遍 `INSTALL.md`(本地 Docker:`python:3.12-slim` 装 wheel → `ops setup` → `ops doctor` → `ops sync` → `ops noc`)。
|
|
250
|
+
`scripts/build-obfuscated.sh`(PyArmor 混淆、仅 arm64 Mac)保留但不再是默认分发路径。
|
|
251
|
+
|
|
252
|
+
## 插件子命令(entry point)
|
|
253
|
+
|
|
254
|
+
公司 / 团队专属的子命令不进公开 wheel,放在自己的私有包里,经 entry point 组 `noc_ops.commands` 挂回 `ops`:
|
|
255
|
+
|
|
256
|
+
```toml
|
|
257
|
+
# 私有包的 pyproject.toml
|
|
258
|
+
[project]
|
|
259
|
+
dependencies = ["noc-ops"]
|
|
260
|
+
[project.entry-points."noc_ops.commands"]
|
|
261
|
+
litellm = "noc_ops_internal.litellm_cli:main" # 被调函数签名 main(argv) -> int | None
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
装法:`uv tool install 'noc-ops[all]' --with <私有包路径或名>`。`ops help` 末尾会列出已装的插件命令;内建命令名不可被插件覆盖;插件加载失败只报该命令、不影响 `ops` 其余功能。插件读自己的配置段用 `deploy_config.section("<段名>")`。
|
|
265
|
+
|
|
266
|
+
## 待办 / 后续
|
|
267
|
+
|
|
268
|
+
- [ ] SSH 通道:配置 `~/.ssh/config`(跳板机 ProxyJump + key 文件),登录元数据进 inventory,私钥/密码不进明文。
|
|
269
|
+
- [ ] 把常用运维逐步沉淀成 runbooks。
|
|
270
|
+
- [ ] 提交前固定跑 `uv run --extra dev pytest -m unit -q`(当前 739 例 / ~2s);有条件再接进 pre-commit hook 或 CI 自动化,别靠人记。
|
|
271
|
+
- [ ] **深信服 HCI 的重启端点未探明**(2026-09-18 实测):provider 里写的 `POST /janus/20180725/servers/{id}/action` 本机 SCP 返回 404,从来没调通过;`ops reboot` 对 sangfor 只有 `--status` 可用(读没问题)。已探明:真口疑似批量的 `POST /janus/20180725/servers/action`,必传 `server_ids` + `server_action`(dict,`{}` 能过校验但 503),但其字段名 36 个候选全被拒、appliance 无 swagger/doc。**最省事的解法**:在 SCP 控制台点一次「重启」,devtools 抓那条 XHR 的 path+payload,照着改 `providers/sangfor.py` 的 `_reboot_server` 即可(考古记录在该文件头注)。在那之前:Linux VM 走 SSH 别名 `reboot`,Windows 去控制台点。
|
|
272
|
+
|
|
273
|
+
## 许可
|
|
274
|
+
|
|
275
|
+
Apache License 2.0,见 `LICENSE` 与 `NOTICE`。看板自托管的第三方前端组件(AG Grid Community / Inter 字体)各随其原许可(MIT / OFL 1.1)。
|