net-connector 0.4.0 → 0.4.2

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +110 -68
  3. data/CONTRIBUTING.md +40 -0
  4. data/README.md +140 -95
  5. data/SECURITY.md +11 -0
  6. data/docs/VERIFICATION.md +129 -5
  7. data/docs/architecture.md +321 -248
  8. data/lib/net/connector/device/base.rb +12 -4
  9. data/lib/net/connector/device/interface_description.rb +3 -0
  10. data/lib/net/connector/device/profile/builder.rb +236 -0
  11. data/lib/net/connector/device/profile.rb +2 -227
  12. data/lib/net/connector/device/running_config/strategy.rb +5 -0
  13. data/lib/net/connector/device/running_config.rb +7 -0
  14. data/lib/net/connector/engine/command.rb +14 -2
  15. data/lib/net/connector/engine/configuration.rb +10 -7
  16. data/lib/net/connector/engine/dialogue.rb +53 -28
  17. data/lib/net/connector/engine/errors.rb +41 -54
  18. data/lib/net/connector/engine/execution.rb +32 -5
  19. data/lib/net/connector/engine/log.rb +23 -17
  20. data/lib/net/connector/engine/session.rb +39 -7
  21. data/lib/net/connector/engine/terminal_renderer.rb +7 -4
  22. data/lib/net/connector/netdisco/batch.rb +31 -3
  23. data/lib/net/connector/netdisco/cli.rb +92 -50
  24. data/lib/net/connector/netdisco/client.rb +206 -73
  25. data/lib/net/connector/netdisco/config_file.rb +26 -4
  26. data/lib/net/connector/netdisco/device.rb +4 -8
  27. data/lib/net/connector/netdisco/diagnostic.rb +91 -0
  28. data/lib/net/connector/netdisco/fleet.rb +105 -108
  29. data/lib/net/connector/netdisco/inventory_budget.rb +49 -0
  30. data/lib/net/connector/netdisco/plan.rb +77 -0
  31. data/lib/net/connector/netdisco/planner.rb +12 -23
  32. data/lib/net/connector/netdisco/report.rb +94 -0
  33. data/lib/net/connector/netdisco/rules.rb +28 -5
  34. data/lib/net/connector/netdisco/settings.rb +194 -85
  35. data/lib/net/connector/netdisco/worker.rb +43 -27
  36. data/lib/net/connector/operations/backup_lock.rb +116 -0
  37. data/lib/net/connector/operations/local_backup.rb +49 -9
  38. data/lib/net/connector/operations/parse_output.rb +20 -3
  39. data/lib/net/connector/operations/private_file.rb +94 -5
  40. data/lib/net/connector/operations/safe_file.rb +62 -0
  41. data/lib/net/connector/operations/saved_config/legacy_index.rb +109 -0
  42. data/lib/net/connector/operations/saved_config.rb +40 -10
  43. data/lib/net/connector/operations/tftp/file_upload.rb +55 -0
  44. data/lib/net/connector/operations/tftp/strategy.rb +9 -11
  45. data/lib/net/connector/operations/tftp_backup.rb +78 -15
  46. data/lib/net/connector/operations/tftp_receipt.rb +73 -0
  47. data/lib/net/connector/operations/topology/immediate_strategy.rb +45 -0
  48. data/lib/net/connector/operations/topology/strategy.rb +34 -0
  49. data/lib/net/connector/operations/topology.rb +98 -29
  50. data/lib/net/connector/operations.rb +6 -0
  51. data/lib/net/connector/vendor/cisco_ios/running_config.rb +1 -0
  52. data/lib/net/connector/vendor/cisco_ios/tftp_backup.rb +9 -2
  53. data/lib/net/connector/vendor/cisco_ios/topology.rb +18 -3
  54. data/lib/net/connector/vendor/cisco_nxos/running_config.rb +1 -0
  55. data/lib/net/connector/vendor/cisco_nxos/tftp_backup.rb +8 -1
  56. data/lib/net/connector/vendor/h3c/tftp_backup.rb +7 -18
  57. data/lib/net/connector/vendor/h3c/topology.rb +17 -3
  58. data/lib/net/connector/vendor/hillstone/running_config.rb +1 -0
  59. data/lib/net/connector/vendor/hillstone/tftp_backup.rb +16 -3
  60. data/lib/net/connector/vendor/hillstone/topology.rb +17 -3
  61. data/lib/net/connector/vendor/huawei/tftp_backup.rb +8 -18
  62. data/lib/net/connector/vendor/palo_alto/running_config.rb +4 -0
  63. data/lib/net/connector/vendor/palo_alto/tftp_backup.rb +19 -8
  64. data/lib/net/connector/vendor/palo_alto/topology.rb +16 -1
  65. data/lib/net/connector/vendor/radware/tftp_backup.rb +11 -4
  66. data/lib/net/connector/vendor/radware/topology.rb +3 -0
  67. data/lib/net/connector/version.rb +1 -1
  68. metadata +60 -28
data/docs/VERIFICATION.md CHANGED
@@ -15,9 +15,10 @@ script/ci
15
15
  | 步骤 | 内容 |
16
16
  | --- | --- |
17
17
  | `security:check` | 扫描待提交源码和可用的完整 Git 历史;拒绝混入源码的本地凭据、配置和产物 |
18
- | `lint` | 对库、脚本、示例、测试、Gemfile、gemspec 和 Rakefile 执行 RuboCop |
18
+ | `lint` | 对库、脚本、示例、测试、Gemfile、gemspec 和 Rakefile 执行 RuboCop;引擎及 Netdisco 方法上限为 40 行、ABC 60 |
19
19
  | `lint:workflows` | 用 actionlint 校验 GitHub Actions 工作流 |
20
- | `test` | 执行全部 Minitest;敏感信息和发布测试使用临时文件、临时仓库与模拟远端响应 |
20
+ | `test` | 执行全部 Minitest,列出未加载文件,并执行关键模块的行与分支覆盖率门槛;敏感信息和发布测试使用临时文件、临时仓库与模拟远端响应 |
21
+ | `benchmark:smoke` | 每项 16 KiB 的合成工作负载,验证假传输、本地 PTY、配置清理、解析、结果保留与日志;只检查正确性,不按机器速度设门槛 |
21
22
  | `package:verify` | 构建 gem,检查元数据、文件白名单、源文件字节和执行位,扫描解包内容及元数据,再进行隔离安装 |
22
23
 
23
24
  隔离安装清除当前 Bundler 和 Ruby 注入变量,分别验证普通 `gem install`
@@ -25,6 +26,96 @@ script/ci
25
26
  PTY 子进程采集配置,读取包内 TextFSM 模板,并检查 CLI。它不连接网络设备,
26
27
  也不证明现场设备协议或真实发布服务已验收。
27
28
 
29
+ ## 配置输出隐私回归
30
+
31
+ `test/output_sensitive_test.rb` 使用每次运行新生成、不同于登录凭据的假秘密,
32
+ 覆盖 text/info、text/debug、raw 和外部 logger;检查成功采集、控制符分片、
33
+ 超时、输出超限、设备错误、厂商追加查询、命令替换、结果选择、清理异常和
34
+ 日志器故障。断言包含错误 message/output、底层 message/backtrace、
35
+ `exception.full_message` 及 cause,同时核对完整结果、备份字节与 SHA-256。
36
+ 还验证普通命令诊断恢复、失败重连、非局部退出及元数据复制。
37
+
38
+ `test/transport_test.rb` 另用本地 Ruby PTY 验证配置日志隔离、控制字符、
39
+ 真实读取超时和子进程回收。厂商覆盖来自合成输出,固件范围为 unknown;
40
+ 这些结果不构成真实设备、真实凭据或生产 TFTP 服务验收。
41
+
42
+ ```sh
43
+ bundle exec ruby -Ilib:test test/output_sensitive_test.rb
44
+ bundle exec ruby -Ilib:test test/redaction_contract_test.rb
45
+ bundle exec ruby -Ilib:test test/transport_test.rb
46
+ bundle exec ruby -Ilib:test test/collection_contract_test.rb
47
+ bundle exec ruby -Ilib:test test/running_config_strategy_test.rb
48
+ bundle exec ruby -Ilib:test test/module_loading_test.rb
49
+ ```
50
+
51
+ 实施记录保存在源码树的 `docs/optimization/`,不进入 gem 发布白名单。
52
+ 每个工作包的初始状态、已运行命令与未验证边界均以该记录中的日期和环境为限。
53
+
54
+ ## 离线内存基准与累计预算
55
+
56
+ `bundle exec ruby script/benchmark_memory.rb --suite baseline --directory tmp/benchmarks/my-run`
57
+ 逐个启动独立 Ruby 进程,报告 1/8/32 MiB 响应、1/10/100 命令、1/4/16 并发的
58
+ 选定组合,不运行最大值的笛卡尔积。单个样本计划响应正文不得超过 128 MiB,
59
+ 已有输出目录拒绝覆盖。较小的 `--suite smoke` 纳入 `rake ci`。
60
+
61
+ 每个样本保留机器信息、实际依赖版本、源码摘要、外部 `/usr/bin/time` 原始统计,
62
+ 以及各阶段的分配对象数、单调耗时、`ps` 测得的 RSS 端点。峰值是 time 的进程
63
+ 高水位,不是 worker/PTY 子进程 RSS 总和;构造夹具和连接在阶段计时前完成,
64
+ 仍计入进程峰值。GC 正常启用。默认日志采用 Configuration 默认值,另有显式
65
+ debug Logger 计数目标样本;不关闭协议检查、丢弃步骤或共享有状态 Parser。
66
+
67
+ 响应构造、终端渲染、配置清理、解析、完整采集与步骤保留分别计量。
68
+ `Result#output` 单次与重复调用单列,不把对象分配数误当字节数,也不据一次采样
69
+ 承诺内存降低比例。带 `--script-budget-bytes N` 的 retain 样本同时验证预算失败
70
+ 及保留输出;它执行的命令较少,不能与完整脚本称为相同工作量的性能提升。
71
+ 基准脚本和原始实施记录不进入运行 gem。
72
+
73
+ `test/script_output_budget_test.rb` 覆盖默认关闭、精确边界、多字节、分页的原始字节、
74
+ 各类钩子追加查询、提示符回调、异常被吞掉后仍失败、故障位置、完整步骤、新脚本
75
+ 重置、原单响应限制及 TFTP 回执。输出隐私矩阵保留日志和原始结果双向断言,
76
+ 真实 PTY 测试核对关闭和 waitpid 回收;设置测试验证优先级、批内不变及离线导出。
77
+
78
+ ## 覆盖率与复杂度门槛
79
+
80
+ `script/coverage.rb` 在测试加载源码前启动 Ruby `Coverage`,由
81
+ `script/coverage_report.rb` 检查以下三个组。各组分别按实际可执行行、分支
82
+ 累计命中比例,不取文件百分比的平均值,不先四舍五入再判断。
83
+
84
+ | 组 | 文件范围 | 行 / 分支最低覆盖率 |
85
+ | --- | --- | --- |
86
+ | 核心引擎 | `lib/net/connector/engine/**/*.rb` | 80% / 80% |
87
+ | 脱敏与错误处理 | `lib/net/connector/engine/errors.rb`,包含 `Redactor` | 80% / 80% |
88
+ | 批量并发 | `lib/net/connector/netdisco/worker.rb` | 80% / 80% |
89
+
90
+ 关键组为空、任一关键文件未测量或组内没有可执行行时均失败。没有分支的组
91
+ 不需要分支命中,但仍须通过行覆盖率及文件加载检查。
92
+ 全库输出中的“未加载文件”表示当前测试进程没有采集到数据:可能只在隔离
93
+ 子进程中加载,也可能在覆盖率启动前被 Bundler 加载,不等同于从未测试。
94
+ 报告会逐项列出路径,不自动预加载源码,也不把子进程覆盖率并入主进程。
95
+
96
+ 每次完整测试同时写入 `tmp/coverage/summary.json`:Ruby 描述和平台、实际依赖版本、
97
+ 库文件总数/已加载数、逐文件及上述三个组的行/分支计数、未命中位置和未加载文件。
98
+ `NET_CONNECTOR_COVERAGE_OUTPUT` 只改变输出位置,不改变门槛。报告不保存配置正文、
99
+ 环境变量值或源码片段。CI 每个 Ruby/平台和最低依赖任务分别上传报告。
100
+
101
+ `script/coverage-baseline.json` 来自 NC-00 实测的初始 dirty 工作树,保存三个组及
102
+ 已加载库总计的原始分数。Ruby 描述(含平台)相同时按整数交叉相乘比较,任一
103
+ 行/分支比例下降均失败;不会自动更新基线。其他运行时标为 `not_comparable`,
104
+ 继续执行原有 80% 门槛与全部行为测试,不能把跨 Ruby 插桩差异当业务回归。
105
+ NC-00 未保存逐文件数据,因此本轮不伪造逐文件历史下限;现在的逐文件报告供后续
106
+ 同环境审阅建立更细基线。基线更新必须审阅,不能用新的低值覆盖旧值来消除失败。
107
+
108
+ 门槛失败由 `Minitest.after_run` 返回非零退出码,`rake test`、`ci`、
109
+ `release:check` 都会失败;测试本身的失败也不会被达标的覆盖率覆盖。
110
+ 单文件开发检查请用 `bundle exec ruby -Ilib -Itest test/<名称>_test.rb`,
111
+ 完整预检仍须运行全部测试,不提供环境变量来降低发布门槛。
112
+
113
+ `.rubocop.yml` 对 `engine/` 和 `netdisco/` 启用 `Metrics/MethodLength`
114
+ (40)及 `Metrics/AbcSize`(60)。这是初始上限;按职责拆分超限方法,
115
+ 不通过自动生成文件豁免维持基线。方法行数按 RuboCop 口径计算。
116
+
117
+ ## 平台与工具
118
+
28
119
  CI 矩阵为 Ubuntu 24.04 / macOS 15 × Ruby 3.2、3.3、3.4、4.0。
29
120
  GitHub Actions 固定提交 SHA;Gitleaks 与 actionlint 固定版本和各平台归档
30
121
  SHA-256,首次使用时从官方 GitHub Release 下载,缓存到 `tmp/tools/`。
@@ -34,16 +125,49 @@ SHA-256,首次使用时从官方 GitHub Release 下载,缓存到 `tmp/tools/
34
125
 
35
126
  ## 依赖与打包
36
127
 
128
+ `test/topology_stages_test.rb` 使用 `test/support/topology_fixture.rb` 的四类合成对话,验证视图转换、先读回后保存、各阶段超时、读回不匹配/不完整、审批与实际查询一致、旧计划拒绝、保存完成证据和重连不重放。Queue 固定读回完成至保存之前的竞争窗口,检查线程和 Fiber 所有权。PAN-OS 无候选隔离证据时在 I/O 前拒绝自动改写,保留只读解析。夹具的官方来源、推断和 unknown 固件范围见 `test/fixtures/topology/README.md`;测试不等于现场设备认证。普通及最小 Bundler 隔离安装另用本地 PTY 验证分阶段拓扑流程及读回输出敏感标记。
129
+
130
+ `test/tftp_boundary_test.rb` 验证内置策略在首次 I/O 前拒绝不支持的参数组合,使用 Queue 固定 H3C 源探测后的竞争窗口,检查线程/Fiber 拒绝。上传确认后的日志、命令清理、租约清理、路径和元数据钩子失败保留回执且不重传;随机假秘密不进入新错误正文。回执测试保留旧 Data 解构/成员,核对配置来源及设备报告等级;Fleet 拒绝第三方和子类提供的完成事实。既有成功/失败/echo/控制符证据用同一套合成夹具继续测试,来源和 unknown 固件范围见 `test/fixtures/tftp/README.md`。普通及最小 Bundler 安装通过本地 PTY 验证新的回执入口,没有连接真实 TFTP 服务器或上传配置。
131
+
132
+ `test/netdisco_reporting_test.rb` 覆盖 strict/selected 的状态决策矩阵、显式 CLI 退出码、默认 JSON 键及 Data 成员/位置参数不变、旧 Fleet/ResultStore 签名,以及部分成功/回调/报告错误阻止 selected 成功。动态假秘密放入异常消息、输出、命令、source、line、phase、code 和自定义类型名,v2 报告与私有 JSON 不得含它。受控文件/TFTP 回执阶段跨 Worker 复制仍保留,普通文件异常不能冒充设备产物。可控时钟让 UTC 倒退而单调时间前进,断言设备及批次耗时准确且无负值;没有用固定睡眠推断时间行为。
133
+
134
+ `test/backup_lock_test.rb` 通过 Queue、独立 Ruby 进程及可控单调时钟检查采集前互斥、有限等待、锁释放、线程/Fiber/回调递归、路径别名、私有权限、硬链接/FIFO 拒绝和符号链接替换。`test/backup_identity_test.rb` 保留旧命名比较及 mtime 契约;稳定锁文件不再作为多余备份计数。
135
+
136
+ `test/legacy_index_test.rb` 用 8 台合成设备和 4 个 worker 统计目录扫描:旧命名迁移一批只扫描一次,规范文件全命中时为零;同一 Fleet 的新批次重新识别歧义。覆盖 IPv6/zone 身份、文件类型、快照失败及文件消失、替换、原位修改;在读返回期间注入修改,断言失效正文不交付。端到端批次验证失效基线在凭据和连接器调用前失败。计数证明扫描次数减少,不代表已经测出墙钟性能提升。
137
+
138
+ `test/module_loading_test.rb` 在独立 Ruby 进程核验 Netdisco 加载、CLI 离线导出和实际解析的 `$LOADED_FEATURES`;旧入口双加载顺序继续检查。`test/parsing_encoding_test.rb` 覆盖 UTF-8/二进制标签、非法 UTF-8、Latin-1 字节、回车/退格/ANSI、被控制符隐藏的非法输入、分裂多字节字符、原备份不变及拓扑不能把异常输出当作空表。原有 PAN-OS 引号多行拒绝及多线程独立解析测试保留。没有真实其他编码设备样本,本次不增加自动或显式设备编码配置;严格转码能力留待实际设备需求验证。
139
+
140
+ `test/file_persistence_test.rb` 对临时文件创建、写入、flush/fsync、rename、父目录打开/同步及收尾注入故障,检查磁盘内容、阶段回执、无正文诊断、Fleet 部分成功及报告/导出行为。同步不支持与 EIO 分开,第三方回执子类不能供应完成事实。隔离安装烟测还通过真实本地 PTY 采集写入,验证私有锁、目录同步及安全读取。本地 macOS 测试证明协议与故障分支;Linux、网络文件系统、真实断电恢复需单独验证。
141
+
142
+ `test/netdisco_budget_test.rb` 用合成响应、可控单调时钟及本地 TCP HTTP 端点验证单页/累计字节、记录数、分页、认证和兼容查询的共用期限。流式上限覆盖 chunked、无长度和虚报长度;超限时设备工厂与凭据解析器均未调用。阻塞读取场景断言关闭自有传输并回收观察线程,不靠固定 sleep 判断竞态。旧 requester 只验证返回后的预算,不声称能强制中止任意回调。
143
+
144
+ `test/netdisco_settings_test.rb` 验证批内 ENV 策略变化被隔离、逐设备凭据轮换、后续批次刷新、批准计划不重抓清单、CLI/ENV/YAML 优先级及离线导出。策略快照的序列化和 inspect 不含秘密;非法枚举、采样范围及预算在创建 Fleet 或设备前拒绝。默认预算没有经过生产容量压测,真实 Netdisco 及多平台远端矩阵仍需单独验收。
145
+
37
146
  运行依赖写在 `net-connector.gemspec`,包括直接使用的、可能从 Ruby 默认
38
147
  安装中拆出的标准库 gem。开发工具只写在 Gemfile,不进入运行依赖。
39
- `expect-pty` 使用 `~> 0.3.1`;开发用 `parallel` 保持 1.x,以支持 Ruby 3.2。
148
+ 共享脱敏要求 `expect-pty ~> 0.5.0`,使用已发布的公共 `Expect::Redactor`。
149
+ 开发及隔离安装检查使用正式依赖包,不再需要本地 expect 补丁或联调环境包装脚本。
150
+ 开发用 `parallel` 保持 1.x,以支持 Ruby 3.2。
40
151
 
41
152
  本项目是库,`Gemfile.lock` 仅作本地开发记录并被忽略;各 Ruby 版本的 CI
42
153
  分别解析兼容依赖。应用使用者应在自己的应用中提交 lockfile。测试和打包
43
154
  脚本通过隔离安装检查运行依赖,避免依赖开发环境里偶然存在的 gem。
44
155
 
45
- gem 只收录库代码、TextFSM 模板、CLI、架构/验证/发布文档、README、LICENSE 和
46
- CHANGELOG。测试、示例、发布工具、工作流、本地评审快照、配置和备份不进入包。
156
+ `gemfiles/minimum.gemfile` 固定关键业务依赖下限 expect-pty 0.5.0、textfsm 0.2.0;
157
+ 标准库和开发工具仍按主 Gemfile 的兼容范围解析。普通矩阵检查允许版本的正常解析,
158
+ 另在 Ubuntu / Ruby 3.2、4.0 检查下限组合的全量测试与隔离安装。本地复现:
159
+
160
+ ```sh
161
+ BUNDLE_GEMFILE=gemfiles/minimum.gemfile bundle install
162
+ BUNDLE_GEMFILE=gemfiles/minimum.gemfile bundle exec rake test package:verify
163
+ ```
164
+
165
+ 这不是所有传递依赖最旧版本的笛卡尔积,也不声称本地 macOS 运行证明远端矩阵通过。
166
+ 当前这两个关键依赖的正常解析与下限恰好相同,报告仍记录实际版本,供以后比较。
167
+ 开发锁文件均忽略;gemspec 保持兼容范围,基准、夹具、兼容 Gemfile 和审阅报告均不进 gem。
168
+
169
+ gem 只收录库代码、TextFSM 模板、CLI、架构/验证/发布文档、README、LICENSE、
170
+ CHANGELOG、SECURITY 和 CONTRIBUTING。测试、示例、发布工具、工作流、本地评审快照、配置和备份不进入包。
47
171
  更改 gemspec 后,实际归档仍须通过独立的文件白名单检查。
48
172
 
49
173
  ## 敏感数据