net-connector 0.20.0 → 0.21.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +4 -0
- data/lib/net/connector/collect/progress.rb +1 -1
- data/lib/net/connector/device/interfaces/audit.rb +2 -2
- data/lib/net/connector/device/interfaces/description.rb +3 -3
- data/lib/net/connector/device/interfaces/neighbor.rb +6 -6
- data/lib/net/connector/device/interfaces.rb +5 -5
- data/lib/net/connector/netdisco/topology/options.rb +3 -3
- data/lib/net/connector/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e379dbe5598c3f170fdcfbc123103c4eb178941508e8fa0df12e2b8043fdf93
|
|
4
|
+
data.tar.gz: 3ad7934b5aa811031ea1a1283c67743494795472a0361207869d6b16d03cfda0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 07e68bd1ebd341839e6c45db6e821e76f8371c7b5d2e135a064925be5ca6f0d06189cf22be97fd2d8ea676fc542216dc67bfeff88fd06043b310fe72e642b67b
|
|
7
|
+
data.tar.gz: 96400e19508ca207d0e4aeccb0dc5aad7529bafebb0e2a4723a10e9d3907e07c5ba9f722afaabf5d78f257184f2b7f27aab82da91c7e64f60ca005188d1aa445
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.21.0 - 2026-10-30
|
|
6
|
+
|
|
7
|
+
- Rename neighbor fields to `remote_name`, `remote_interface` and `remote_chassis_id`, retaining `local_interface`. Collection progress reads schema 4 `target`; require ctx_cli 0.5. No legacy accessor aliases.
|
|
8
|
+
|
|
5
9
|
## 0.20.0 - 2026-10-29
|
|
6
10
|
|
|
7
11
|
- Require the latest stable TextFSM 0.5.1, align the minimum dependency matrix, and verify JSON 3 with its original published package instead of a source metadata patch.
|
data/README.md
CHANGED
|
@@ -85,3 +85,7 @@ credentials = Net::Connector::Credentials.new(env: ENV).resolve(platform: :cisco
|
|
|
85
85
|
Catalog owns inventory reading, normalization, duplicate marking and cache status (`#status`). It does not resolve device credentials, log into devices or create operation reports. Pass one policy snapshot throughout a run. Fleet delegates to Catalog and retains operation orchestration.
|
|
86
86
|
|
|
87
87
|
Credentials reads the injected environment on every `resolve`; it returns an independent frozen hash, or nil when no username is available. Platform-specific `NC_<PLATFORM>_USERNAME`, `_PASSWORD`, and `_ENABLE_PASSWORD` override `NC_DEVICE_USERNAME`, `NC_DEVICE_PASSWORD`, and `NC_ENABLE_PASSWORD` respectively. Blank values fall back. Secrets are never cached or included in object inspection.
|
|
88
|
+
|
|
89
|
+
## Domain contract migration (2026-10-30)
|
|
90
|
+
|
|
91
|
+
Rename neighbor fields to `remote_name`, `remote_interface` and `remote_chassis_id`, retaining `local_interface`. Collection progress reads schema 4 `target`; require ctx_cli 0.5. No legacy accessor aliases. See the [schema 4 migration and module contracts](https://github.com/gatework/ctx_runner/blob/main/docs/contracts-2026-10-30.md). Regenerate old collection reports and change plans; changing only their version number is not supported.
|
|
@@ -27,7 +27,7 @@ module Net
|
|
|
27
27
|
when "partial" then "Partially complete (#{code})"
|
|
28
28
|
else "Incomplete (#{code})"
|
|
29
29
|
end
|
|
30
|
-
super(host: result.fetch("
|
|
30
|
+
super(host: result.fetch("target").fetch("host"), success: status == "complete",
|
|
31
31
|
duration_ms: result.fetch("duration_ms"), message: message, error_code: code&.to_sym)
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -64,7 +64,7 @@ module Net
|
|
|
64
64
|
def inspect_interface(interface, peers)
|
|
65
65
|
peer = peers.first
|
|
66
66
|
current = @descriptions[interface]
|
|
67
|
-
row = { interface: peer.local_interface, neighbor: peer.
|
|
67
|
+
row = { interface: peer.local_interface, neighbor: peer.remote_name, port: peer.remote_interface,
|
|
68
68
|
current: current, expected: nil, status: :unverified }
|
|
69
69
|
@comparisons << row
|
|
70
70
|
if peers.size != 1
|
|
@@ -78,7 +78,7 @@ module Net
|
|
|
78
78
|
local = @strategy.configuration_interface(peer.local_interface)
|
|
79
79
|
Description.validate_interface!(local)
|
|
80
80
|
row.merge!(expected: proposed, status: compare_status(current, proposed, peer))
|
|
81
|
-
@evidence[interface] = [peer.
|
|
81
|
+
@evidence[interface] = [peer.remote_name, peer.remote_interface, current]
|
|
82
82
|
return if row[:status] == :matches
|
|
83
83
|
|
|
84
84
|
@changes << Change.new(interface: local, old_description: current, new_description: proposed, neighbor: peer)
|
|
@@ -10,11 +10,11 @@ module Net
|
|
|
10
10
|
# 将邻居名称和接口拼成默认描述;统一邻居接口简称,原始发现记录保持不变。
|
|
11
11
|
def self.format(neighbor, abbreviate: true, lowercase: false)
|
|
12
12
|
port = if abbreviate
|
|
13
|
-
Name.short(neighbor.
|
|
13
|
+
Name.short(neighbor.remote_interface, lowercase: lowercase)
|
|
14
14
|
else
|
|
15
|
-
lowercase ? neighbor.
|
|
15
|
+
lowercase ? neighbor.remote_interface.downcase : neighbor.remote_interface
|
|
16
16
|
end
|
|
17
|
-
validate!("To_#{neighbor.
|
|
17
|
+
validate!("To_#{neighbor.remote_name.tr(" ", "_")}_#{port.tr(" ", "_")}")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# 保留语义相同的旧描述;只归一末尾已知接口别名和大小写,不模糊匹配名称或端口编号。
|
|
@@ -4,11 +4,11 @@ module Net
|
|
|
4
4
|
module Connector
|
|
5
5
|
class Interfaces
|
|
6
6
|
# 邻居身份拥有独立字符串,格式化回调不能改写发现证据。
|
|
7
|
-
Neighbor = Data.define(:local_interface, :
|
|
7
|
+
Neighbor = Data.define(:local_interface, :remote_name, :remote_interface, :remote_chassis_id, :protocol) do
|
|
8
8
|
# 复制并冻结本地端口、邻居名称、远端端口及发现协议。
|
|
9
|
-
def initialize(local_interface:,
|
|
10
|
-
fields = { local_interface: local_interface,
|
|
11
|
-
|
|
9
|
+
def initialize(local_interface:, remote_name:, remote_interface:, remote_chassis_id:, protocol:)
|
|
10
|
+
fields = { local_interface: local_interface, remote_name: remote_name,
|
|
11
|
+
remote_interface: remote_interface, remote_chassis_id: remote_chassis_id }
|
|
12
12
|
raise ArgumentError, "neighbor fields must be Strings" unless fields.values.all?(String)
|
|
13
13
|
raise ArgumentError, "neighbor protocol must be a Symbol" unless protocol.is_a?(Symbol)
|
|
14
14
|
|
|
@@ -18,8 +18,8 @@ module Net
|
|
|
18
18
|
# 原始发现数据保留占位符;规划与下发重验共用身份校验,不能把未知名称写入描述。
|
|
19
19
|
# MAC 是合法的 LLDP Port ID,不凭地址形状猜测设备角色,也不拿 chassis ID 补造名称。
|
|
20
20
|
def identity_issue
|
|
21
|
-
return :unknown_neighbor_name if unknown_identity?(
|
|
22
|
-
return :unknown_neighbor_interface if unknown_identity?(
|
|
21
|
+
return :unknown_neighbor_name if unknown_identity?(remote_name)
|
|
22
|
+
return :unknown_neighbor_interface if unknown_identity?(remote_interface)
|
|
23
23
|
|
|
24
24
|
nil
|
|
25
25
|
end
|
|
@@ -88,9 +88,9 @@ module Net
|
|
|
88
88
|
|
|
89
89
|
rows.map do |row|
|
|
90
90
|
Neighbor.new(local_interface: row.fetch("LOCAL_INTERFACE").strip.freeze,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
remote_name: row.fetch("NEIGHBOR_NAME", "").strip.freeze,
|
|
92
|
+
remote_interface: row.fetch("NEIGHBOR_INTERFACE").strip.freeze,
|
|
93
|
+
remote_chassis_id: row.fetch("CHASSIS_ID", "").strip.freeze,
|
|
94
94
|
protocol: @strategy.protocol).freeze
|
|
95
95
|
end
|
|
96
96
|
end
|
|
@@ -272,7 +272,7 @@ module Net
|
|
|
272
272
|
plan.changes.each do |change|
|
|
273
273
|
Description.validate!(change.new_description)
|
|
274
274
|
unless evidence.fetch(@strategy.interface_key(change.interface)) ==
|
|
275
|
-
[change.neighbor.
|
|
275
|
+
[change.neighbor.remote_name, change.neighbor.remote_interface, change.old_description]
|
|
276
276
|
raise ArgumentError, "plan changes do not match its discovery evidence"
|
|
277
277
|
end
|
|
278
278
|
end
|
|
@@ -319,7 +319,7 @@ module Net
|
|
|
319
319
|
|
|
320
320
|
interfaces.transform_values do |peers|
|
|
321
321
|
peer = peers.fetch(0)
|
|
322
|
-
[peer.
|
|
322
|
+
[peer.remote_name, peer.remote_interface, current.fetch(@strategy.interface_key(peer.local_interface))].freeze
|
|
323
323
|
end.freeze
|
|
324
324
|
end
|
|
325
325
|
|
|
@@ -51,10 +51,10 @@ module Net
|
|
|
51
51
|
|
|
52
52
|
# 使用当前模板和端口展示策略生成缺失或确需修正的目标描述。
|
|
53
53
|
def description_for(neighbor)
|
|
54
|
-
port = neighbor.
|
|
54
|
+
port = neighbor.remote_interface
|
|
55
55
|
port = Net::Connector::Interfaces::Name.short(port) if abbreviate_ports
|
|
56
56
|
port = port.downcase if lowercase_ports
|
|
57
|
-
format(neighbor: neighbor.
|
|
57
|
+
format(neighbor: neighbor.remote_name, port: port)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# 仅显式声明的旧名称前缀可保留;不把未知名称、包含匹配或不同编号当作同一邻居。
|
|
@@ -63,7 +63,7 @@ module Net
|
|
|
63
63
|
return true if comparison.equivalent?(current, expected)
|
|
64
64
|
|
|
65
65
|
neighbor_name_prefixes.any? do |prefix|
|
|
66
|
-
variant = neighbor.with(
|
|
66
|
+
variant = neighbor.with(remote_name: prefix + neighbor.remote_name)
|
|
67
67
|
comparison.equivalent?(current, description_for(variant))
|
|
68
68
|
end
|
|
69
69
|
end
|
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.
|
|
4
|
+
version: 0.21.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- net-connector contributors
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-30 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ctx_cli
|
|
@@ -15,20 +15,20 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.5.0
|
|
19
19
|
- - "<"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: '0.
|
|
21
|
+
version: '0.6'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
25
|
requirements:
|
|
26
26
|
- - ">="
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: 0.
|
|
28
|
+
version: 0.5.0
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
|
-
version: '0.
|
|
31
|
+
version: '0.6'
|
|
32
32
|
- !ruby/object:Gem::Dependency
|
|
33
33
|
name: expect-pty
|
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|