net-connector 0.7.3 → 0.9.0

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/CONTRIBUTING.md +12 -0
  4. data/README.md +27 -424
  5. data/README.zh-CN.md +64 -0
  6. data/{exe/net-connector-backup → bin/net-backup} +1 -0
  7. data/docs/VERIFICATION.md +2 -2
  8. data/docs/architecture.md +27 -5
  9. data/docs/netdisco.md +176 -0
  10. data/docs/netdisco.zh-CN.md +247 -0
  11. data/docs/usage.md +124 -0
  12. data/docs/usage.zh-CN.md +190 -0
  13. data/examples/backup.yml +5 -4
  14. data/examples/inventory_sql.yml +5 -1
  15. data/lib/net/connector/device/base.rb +12 -5
  16. data/lib/net/connector/device/local_backup.rb +3 -0
  17. data/lib/net/connector/device/running_config/strategy.rb +2 -1
  18. data/lib/net/connector/device/running_config.rb +2 -0
  19. data/lib/net/connector/device/tftp/receipt.rb +1 -0
  20. data/lib/net/connector/device/tftp/strategy.rb +28 -9
  21. data/lib/net/connector/device/tftp.rb +23 -16
  22. data/lib/net/connector/device/topology/immediate_strategy.rb +2 -1
  23. data/lib/net/connector/engine/authentication.rb +1 -0
  24. data/lib/net/connector/engine/core.rb +1 -0
  25. data/lib/net/connector/engine/dialogue.rb +5 -134
  26. data/lib/net/connector/engine/errors.rb +0 -92
  27. data/lib/net/connector/engine/known_hosts.rb +20 -4
  28. data/lib/net/connector/engine/log.rb +27 -6
  29. data/lib/net/connector/engine/recovery.rb +1 -1
  30. data/lib/net/connector/engine/redactor.rb +98 -0
  31. data/lib/net/connector/engine/response_reader.rb +139 -0
  32. data/lib/net/connector/engine/session.rb +20 -7
  33. data/lib/net/connector/engine/transport.rb +21 -10
  34. data/lib/net/connector/netdisco/backup_run.rb +35 -8
  35. data/lib/net/connector/netdisco/cli/options.rb +20 -8
  36. data/lib/net/connector/netdisco/cli.rb +14 -11
  37. data/lib/net/connector/netdisco/config_file.rb +19 -14
  38. data/lib/net/connector/netdisco/connection.rb +0 -1
  39. data/lib/net/connector/netdisco/database_client.rb +44 -26
  40. data/lib/net/connector/netdisco/device.rb +5 -0
  41. data/lib/net/connector/netdisco/diagnostic.rb +8 -0
  42. data/lib/net/connector/netdisco/fleet.rb +12 -3
  43. data/lib/net/connector/netdisco/plan.rb +16 -3
  44. data/lib/net/connector/netdisco/planner.rb +2 -1
  45. data/lib/net/connector/netdisco/progress.rb +31 -7
  46. data/lib/net/connector/netdisco/report/files.rb +4 -2
  47. data/lib/net/connector/netdisco/result_store.rb +6 -7
  48. data/lib/net/connector/netdisco/rules.rb +8 -5
  49. data/lib/net/connector/netdisco/settings.rb +83 -19
  50. data/lib/net/connector/netdisco/tftp_archive.rb +6 -3
  51. data/lib/net/connector/netdisco/tftp_verification.rb +1 -0
  52. data/lib/net/connector/netdisco/worker.rb +3 -1
  53. data/lib/net/connector/netdisco.rb +1 -21
  54. data/lib/net/connector/storage/private_file.rb +6 -0
  55. data/lib/net/connector/vendor/cisco_ios/running_config.rb +1 -0
  56. data/lib/net/connector/vendor/cisco_ios/tftp_backup.rb +2 -0
  57. data/lib/net/connector/vendor/cisco_ios/topology.rb +2 -0
  58. data/lib/net/connector/vendor/cisco_nxos/tftp_backup.rb +2 -0
  59. data/lib/net/connector/vendor/h3c/tftp_backup.rb +1 -0
  60. data/lib/net/connector/vendor/h3c/topology.rb +2 -0
  61. data/lib/net/connector/vendor/hillstone/running_config.rb +1 -0
  62. data/lib/net/connector/vendor/hillstone/tftp_backup.rb +2 -0
  63. data/lib/net/connector/vendor/hillstone/topology.rb +2 -0
  64. data/lib/net/connector/vendor/huawei/tftp_backup.rb +2 -1
  65. data/lib/net/connector/vendor/palo_alto/running_config.rb +27 -6
  66. data/lib/net/connector/vendor/palo_alto/tftp_backup.rb +2 -0
  67. data/lib/net/connector/vendor/palo_alto/topology.rb +16 -16
  68. data/lib/net/connector/vendor/radware/running_config.rb +1 -0
  69. data/lib/net/connector/vendor/radware/tftp_backup.rb +2 -0
  70. data/lib/net/connector/vendor/radware/topology.rb +1 -0
  71. data/lib/net/connector/version.rb +2 -1
  72. data/lib/net/connector.rb +1 -0
  73. data/lib/net-connector.rb +1 -0
  74. metadata +12 -20
  75. data/lib/net/connector/netdisco/tftp_history.rb +0 -16
@@ -6,6 +6,7 @@ require_relative "../../device/running_config/strategy"
6
6
  module Net
7
7
  module Connector
8
8
  module PaloAlto
9
+ # 通过候选差异与 set 格式校验确认采集证据,拒绝将未提交配置当作运行配置。
9
10
  class RunningConfig < Net::Connector::RunningConfig::Strategy
10
11
  # 配置位于 show 步骤,最后的 exit 只负责离开候选视图。
11
12
  def result_step(result)
@@ -48,19 +49,39 @@ module Net
48
49
  return false if text.empty?
49
50
 
50
51
  pending = +""
52
+ quote = nil
51
53
  text.each_line do |line|
52
54
  next if pending.empty? && line.strip.empty?
53
55
  return false if pending.empty? && !line.start_with?("set ")
54
56
 
55
57
  pending << line
56
- begin
57
- Shellwords.split(pending)
58
- pending.clear
59
- rescue ArgumentError
60
- # 未闭合引号继续读取;末尾仍未闭合则拒绝整个采集结果。
61
- end
58
+ quote = quote_after(line, quote)
59
+ next if quote
60
+
61
+ Shellwords.split(pending)
62
+ pending.clear
62
63
  end
63
64
  pending.empty?
65
+ rescue ArgumentError
66
+ false
67
+ end
68
+
69
+ # 每行只扫描新增字节,整条逻辑命令闭合后才交给 Shellwords 校验。
70
+ # 单引号中的反斜杠是普通字符;其他位置的转义只影响紧随的一个字节。
71
+ def quote_after(line, quote)
72
+ escaped = false
73
+ line.each_byte do |byte|
74
+ if escaped
75
+ escaped = false
76
+ elsif byte == 92 && quote != 39
77
+ escaped = true
78
+ elsif byte == quote
79
+ quote = nil
80
+ elsif quote.nil? && (byte == 34 || byte == 39)
81
+ quote = byte
82
+ end
83
+ end
84
+ quote
64
85
  end
65
86
 
66
87
  # 去掉命令回显和提示符,保留真正需要校验的设备响应。
@@ -5,6 +5,7 @@ require_relative "../../device/tftp/strategy"
5
5
  module Net
6
6
  module Connector
7
7
  module PaloAlto
8
+ # PAN-OS 上传固定的 running-config.xml,调用方不能改名或指定其他源文件。
8
9
  class TftpBackup < Tftp::Strategy
9
10
  FILENAME = "running-config.xml"
10
11
 
@@ -20,6 +21,7 @@ module Net
20
21
  raise ArgumentError, "PAN-OS TFTP export uses the fixed filename #{FILENAME}"
21
22
  end
22
23
 
24
+ # 声明本厂商实际导出的配置种类与格式,不推断服务器文件已核验。
23
25
  def receipt_metadata(_target, **)
24
26
  { configuration_kind: :running, format: :xml, source_file: FILENAME }
25
27
  end
@@ -5,12 +5,14 @@ require_relative "../../device/topology/strategy"
5
5
  module Net
6
6
  module Connector
7
7
  module PaloAlto
8
+ # 仅开放 LLDP 和描述读取;未验证候选隔离协议前不开放自动提交。
8
9
  class Topology < Topology::Strategy
9
10
  # 候选配置缺少经固件实验确认的所有权/commit 协议,暂只提供读取能力。
10
11
  def self.supports?(capability)
11
12
  %i[neighbors interface_descriptions].include?(capability)
12
13
  end
13
14
 
15
+ # 关闭自动修改时返回固定领域错误,调用方不能把未实现能力当作成功。
14
16
  def change_error_code = :candidate_isolation_unavailable
15
17
 
16
18
  # 读取各本机接口的 LLDP 邻居详情。
@@ -35,22 +37,6 @@ module Net
35
37
  !blocks.empty? && blocks.all? { |block| empty_neighbor_block?(block) }
36
38
  end
37
39
 
38
- private
39
-
40
- # PAN-OS 会列出启用 LLDP、但没有邻居的本机接口;只有明确为空的
41
- # Neighbor information 块可跳过,缺字段的非空块继续交给数量校验拒绝。
42
- def neighbor_blocks(output)
43
- output.split(/^\s*Local information:\s*$/i).select { |block| block.match?(/^\s*Local interface:\s*\S+/i) }
44
- end
45
-
46
- # 邻居字段区只有空行和提示符时,才视为明确的空块。
47
- def empty_neighbor_block?(block)
48
- tail = block.split(/^\s*Neighbor information:\s*$/i, 2)
49
- tail.size == 2 && tail.last.lines.all? { |line| line.strip.empty? || line.match?(/^\S+[>#]\s*$/) }
50
- end
51
-
52
- public
53
-
54
40
  # 模板按行读取;未闭合的引号表示证据不完整,不能把首行当成旧描述。
55
41
  def decode_description(value)
56
42
  value = value.strip
@@ -69,6 +55,20 @@ module Net
69
55
  def script_command(command)
70
56
  command == "commit" ? Command.new(command, timeout: 300) : command
71
57
  end
58
+
59
+ private
60
+
61
+ # PAN-OS 会列出启用 LLDP、但没有邻居的本机接口;只有明确为空的
62
+ # Neighbor information 块可跳过,缺字段的非空块继续交给数量校验拒绝。
63
+ def neighbor_blocks(output)
64
+ output.split(/^\s*Local information:\s*$/i).select { |block| block.match?(/^\s*Local interface:\s*\S+/i) }
65
+ end
66
+
67
+ # 邻居字段区只有空行和提示符时,才视为明确的空块。
68
+ def empty_neighbor_block?(block)
69
+ tail = block.split(/^\s*Neighbor information:\s*$/i, 2)
70
+ tail.size == 2 && tail.last.lines.all? { |line| line.strip.empty? || line.match?(/^\S+[>#]\s*$/) }
71
+ end
72
72
  end
73
73
  end
74
74
  end
@@ -5,6 +5,7 @@ require_relative "../../device/running_config/strategy"
5
5
  module Net
6
6
  module Connector
7
7
  module Radware
8
+ # 复用终端渲染策略,在配置菜单中保持已认证的设备提示身份。
8
9
  class RunningConfig < Net::Connector::RunningConfig::Rendered
9
10
  # /cfg/dump 进入 Configuration 菜单;保留设备前缀,只替换菜单名称。
10
11
  def prompt_text(command)
@@ -5,6 +5,7 @@ require_relative "../../device/tftp/strategy"
5
5
  module Net
6
6
  module Connector
7
7
  module Radware
8
+ # 交互导出 Alteon 原生 tgz 归档;回执不将归档推断为文本运行配置。
8
9
  class TftpBackup < Tftp::Strategy
9
10
  # Radware 原生导出生成压缩配置归档。
10
11
  def self.file_extension = "tgz"
@@ -15,6 +16,7 @@ module Net
15
16
  raise ArgumentError, "Radware TFTP backup does not use vrf" unless vrf.nil?
16
17
  end
17
18
 
19
+ # 声明本厂商实际导出的配置种类与格式,不推断服务器文件已核验。
18
20
  def receipt_metadata(_target, **) = { configuration_kind: :native_archive, format: :tgz }
19
21
 
20
22
  # 构造当前厂商的 TFTP 导出交互脚本。
@@ -5,6 +5,7 @@ require_relative "../../device/topology/strategy"
5
5
  module Net
6
6
  module Connector
7
7
  module Radware
8
+ # 只读取 Alteon 端口名称,不声明邻居发现或描述改写能力。
8
9
  class Topology < Topology::Strategy
9
10
  # Alteon 只支持读取端口描述,不提供邻居发现或自动改写。
10
11
  def self.supports?(capability) = capability == :interface_descriptions
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Net
4
4
  module Connector
5
- VERSION = "0.7.3"
5
+ # gemspec、CLI 与发布工具共用此版本,运行时读取不触发设备依赖加载。
6
+ VERSION = "0.9.0"
6
7
  end
7
8
  end
data/lib/net/connector.rb CHANGED
@@ -4,6 +4,7 @@ require_relative "connector/version"
4
4
  require_relative "connector/device/base"
5
5
 
6
6
  module Net
7
+ # 设备 API 的公开加载入口;只登记厂商名称,实际连接器在首次选择时加载。
7
8
  module Connector
8
9
  VENDORS = {
9
10
  h3c: "H3c",
data/lib/net-connector.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # gem 名称加载入口与 net/connector 共用实现,不额外加载 Netdisco。
3
4
  require_relative "net/connector"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-connector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - net-connector contributors
8
- bindir: exe
8
+ bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-07 00:00:00.000000000 Z
10
+ date: 2026-10-11 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: expect-pty
@@ -65,20 +65,6 @@ dependencies:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '3.1'
68
- - !ruby/object:Gem::Dependency
69
- name: english
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '0.7'
75
- type: :runtime
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: '0.7'
82
68
  - !ruby/object:Gem::Dependency
83
69
  name: fileutils
84
70
  requirement: !ruby/object:Gem::Requirement
@@ -333,7 +319,7 @@ dependencies:
333
319
  version: '0.2'
334
320
  description: 通过 SSH 或 Telnet 登录网络设备,采集配置、执行命令脚本、处理交互提示,并提供脱敏日志与基于 Netdisco 清单的批量备份。
335
321
  executables:
336
- - net-connector-backup
322
+ - net-backup
337
323
  extensions: []
338
324
  extra_rdoc_files: []
339
325
  files:
@@ -341,13 +327,18 @@ files:
341
327
  - CONTRIBUTING.md
342
328
  - LICENSE
343
329
  - README.md
330
+ - README.zh-CN.md
344
331
  - SECURITY.md
332
+ - bin/net-backup
345
333
  - docs/RELEASING.md
346
334
  - docs/VERIFICATION.md
347
335
  - docs/architecture.md
336
+ - docs/netdisco.md
337
+ - docs/netdisco.zh-CN.md
338
+ - docs/usage.md
339
+ - docs/usage.zh-CN.md
348
340
  - examples/backup.yml
349
341
  - examples/inventory_sql.yml
350
- - exe/net-connector-backup
351
342
  - lib/net-connector.rb
352
343
  - lib/net/connector.rb
353
344
  - lib/net/connector/device/base.rb
@@ -382,6 +373,8 @@ files:
382
373
  - lib/net/connector/engine/log/messages.rb
383
374
  - lib/net/connector/engine/log/stream.rb
384
375
  - lib/net/connector/engine/recovery.rb
376
+ - lib/net/connector/engine/redactor.rb
377
+ - lib/net/connector/engine/response_reader.rb
385
378
  - lib/net/connector/engine/result.rb
386
379
  - lib/net/connector/engine/session.rb
387
380
  - lib/net/connector/engine/terminal_renderer.rb
@@ -410,7 +403,6 @@ files:
410
403
  - lib/net/connector/netdisco/rules.rb
411
404
  - lib/net/connector/netdisco/settings.rb
412
405
  - lib/net/connector/netdisco/tftp_archive.rb
413
- - lib/net/connector/netdisco/tftp_history.rb
414
406
  - lib/net/connector/netdisco/tftp_verification.rb
415
407
  - lib/net/connector/netdisco/worker.rb
416
408
  - lib/net/connector/storage.rb
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "tftp_archive"
4
-
5
- module Net
6
- module Connector
7
- module Netdisco
8
- # Compatibility with the first batch archive entry point.
9
- class TftpHistory < TftpArchive
10
- def initialize(server:, **options) # rubocop:disable Lint/UnusedMethodArgument -- Accept the former constructor keyword.
11
- super(**options)
12
- end
13
- end
14
- end
15
- end
16
- end