From 1ea12fd738dfb9d399394dd2bd4d8dfcca737c27 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Sun, 13 Sep 2026 06:26:26 +0100 Subject: [PATCH 1/3] feat(tl1): Infinera and Cisco ONS templates, and TL1 stops being a Ciena exception TL1 templates used to be described as a standing exception to the directory rule: Pro-only templates that sit in a vendor directory. Three separate places said so. With three TL1 vendors that framing does not survive, and it was never really an exception. Edition follows the capability a template uses, never the directory it sits in. cisco/ is now a mixed-edition directory, deliberately. Adds: infinera/infinera-dtnx-tl1-ssh.yml community-tested infinera/infinera-dtnx-tl1-telnet.yml community-tested cisco/cisco-ons15454-tl1-ssh.yml untested-starter cisco/cisco-ons15454-tl1-telnet.yml untested-starter The Cisco pair is untested-starter on purpose. It was built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's TL1 reference, not from a session capture. The status vocabulary exists for exactly this, and the templates say so in their own header as well as in cisco/README.md. connect.tl1Vendor is the 48th key: ciena (default), infinera or cisco-ons. It selects the neighbour verb, the record format, the node's prompt, and whether a routed reply's header SID can be verified at all. An unrecognised value fails the collection rather than falling back, because a typo collecting as the wrong vendor parses nothing, reports no elements, and flags every element behind that gateway as missing on the next run. docs/TL1.md is new: the vendor-neutral half of what ciena/README.md used to state as universal. ciena/README.md keeps only what a 6500 actually does differently, which turns out to be the password quirk, the RTRV-NE-LIST record shape, and echoing the TID in a routed response header. Ciena templates gain tl1Vendor: ciena and drop tl1NeighbourCmd. Its old default, RTRV-NBR:ALL, named a command no shipped node answers. cisco/README.md was 15 lines of caveats with three typos and no template table. It now lists all ten templates with their edition, and keeps the FTD prompt and WLC guidance that were the only content worth keeping. The validator now requires a vendor template's filename to start with its directory name. Every file in the library already satisfied it, so this costs nothing and catches a Ciena template dropped into cisco/, which would otherwise parse, validate, and be findable by nobody. Verified it errors on a deliberate misfile. Also corrects counts that disagreed with each other before this change: the key count was stated as 47 in four files while EDITIONS.md called it "13 Pro-only" in a heading above a paragraph saying 14, and the README template badge was one short of the real count. Validator: 83 templates, 0 errors, 2 pre-existing warnings. Every relative markdown link resolves. ASCII only, per CLAUDE.md. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 35 ++++++++ README.md | 12 ++- ciena/README.md | 67 +++++---------- ciena/ciena-6500-tl1-ssh.yml | 4 +- ciena/ciena-6500-tl1-telnet.yml | 4 +- cisco/README.md | 70 ++++++++++++++-- cisco/cisco-ons15454-tl1-ssh.yml | 22 +++++ cisco/cisco-ons15454-tl1-telnet.yml | 23 ++++++ docs/CONTRIBUTING.md | 2 +- docs/EDITIONS.md | 14 ++-- docs/TEMPLATES.md | 11 +-- docs/TL1.md | 114 ++++++++++++++++++++++++++ infinera/README.md | 53 ++++++++++++ infinera/infinera-dtnx-tl1-ssh.yml | 20 +++++ infinera/infinera-dtnx-tl1-telnet.yml | 21 +++++ pro-features/README.md | 7 +- scripts/validate_templates.py | 18 +++- 17 files changed, 419 insertions(+), 78 deletions(-) create mode 100644 cisco/cisco-ons15454-tl1-ssh.yml create mode 100644 cisco/cisco-ons15454-tl1-telnet.yml create mode 100644 docs/TL1.md create mode 100644 infinera/README.md create mode 100644 infinera/infinera-dtnx-tl1-ssh.yml create mode 100644 infinera/infinera-dtnx-tl1-telnet.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ae6491..ef67fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,41 @@ A major version here means paths changed. Every rename and deletion is mapped in - `juniper/juniper-junos-ssh-noenable-kex.yml`, adding the new `kexOverride` / `kexAlgorithms` connect keys to force a legacy KEX algorithm list for JunOS devices that don't negotiate cleanly against phpseclib's modern defaults. +- **Infinera DTN-X TL1 templates** (`infinera/infinera-dtnx-tl1-ssh.yml`, + `infinera/infinera-dtnx-tl1-telnet.yml`) and an `infinera/README.md`. A DTN-X presents `>` + rather than `<`, pages its neighbour response, and answers a routed command under its own + system name instead of the TID addressed. All three break assumptions carried over from Ciena. +- **Cisco ONS 15454 TL1 templates** (`cisco/cisco-ons15454-tl1-ssh.yml`, + `cisco/cisco-ons15454-tl1-telnet.yml`), shipped `untested-starter`. Built from the Cisco ONS + SONET TL1 Command Guide R9.1 and Oracle's TL1 reference, **not from a session capture**. Its + records are positional rather than keyword-based, and it is the one TL1 platform that reports a + real model per element. +- **`connect.tl1Vendor`**, the 48th key: `ciena` (default), `infinera` or `cisco-ons`. Selects the + neighbour verb, the record format, the prompt, and whether a routed reply's SID can be verified. + An unrecognised value fails the collection rather than falling back. +- **`docs/TL1.md`**, a vendor-neutral guide to TL1: in-band login, gateways and dual-homed + elements, connection limits, and a table of what actually differs between the three platforms. +- `cisco/README.md` rewritten from 15 lines of caveats into a full template table, the ONS 15454 + section, and the existing FTD and WLC guidance with its typos fixed. + +### Changed +- **The "TL1 templates live in `ciena/`" exception is gone.** TL1 templates live with their + vendor, like every other template here, which makes `cisco/` a mixed-edition directory. + Edition follows the capability a template uses, never the directory. Restated in + `docs/EDITIONS.md` and `pro-features/README.md`. +- Ciena templates now carry `tl1Vendor: ciena` and no longer set `tl1NeighbourCmd`. The old + default, `RTRV-NBR:ALL`, named a command no shipped node answers; each vendor's real command is + the default now. rConfig substitutes it and logs a warning for templates still naming the old + verb. +- `ciena/README.md` keeps only what is Ciena-specific. The shared TL1 concepts it used to state as + universal moved to `docs/TL1.md`. +- `scripts/validate_templates.py` now requires a vendor template's filename to start with its + directory name. Every file in the library already did; it is worth enforcing now that one + protocol spans three vendor directories. +- Key counts corrected to 48 across `docs/TEMPLATES.md`, `docs/EDITIONS.md`, + `docs/CONTRIBUTING.md` and `README.md`, which disagreed with each other at 47/13/14. +- README badges corrected to 38 vendors and 74 templates. The template count was already one + short before this change. ## [2.0.0] - 2026-08-16 diff --git a/README.md b/README.md index 8dc41b1..72e04c8 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@

- Vendors Badge - Templates Badge + Vendors Badge + Templates Badge

@@ -134,12 +134,18 @@ hardware model belongs in the filename and when it does not. ## Template keys This README carries no key documentation. The full reference lives in -[docs/TEMPLATES.md](docs/TEMPLATES.md): 47 keys across 7 sections, each with its type, accepted +[docs/TEMPLATES.md](docs/TEMPLATES.md): 48 keys across 7 sections, each with its type, accepted values, default, and which protocols read it. If your device needs behaviour no existing key can express, open a [new key request](https://github.com/rconfig/rConfig-templates/issues/new?template=new-key-request.yml). +## Optical transport (TL1) + +Ciena 6500, Infinera DTN-X and Cisco ONS 15454 are managed over TL1 rather than a CLI, which +behaves differently enough to have its own guide: [docs/TL1.md](docs/TL1.md). Their templates sit +with their vendor like everything else. TL1 is Pro only on every platform. + ## Community - Open an [issue](https://github.com/rconfig/rConfig-templates/issues) for a bug, a question, or a template request diff --git a/ciena/README.md b/ciena/README.md index f0c4f25..3ed307b 100644 --- a/ciena/README.md +++ b/ciena/README.md @@ -7,61 +7,38 @@ Covers Ciena 6500 optical nodes, managed over TL1 rather than a conventional CLI | `ciena-6500-tl1-ssh.yml` | 6500 nodes reached over SSH, TL1 carried on the SSH channel | | `ciena-6500-tl1-telnet.yml` | 6500 nodes reached over raw TCP on a TL1 port, typically 3082/3083 | -Typical retrieval commands to attach in an rConfig Command Group: +**Read [docs/TL1.md](../docs/TL1.md) first.** It covers what TL1 is, in-band `ACT-USER` login, +gateways and dual-homed elements, and `tl1MaxConnections`, none of which is Ciena-specific. What +follows is only what is particular to a 6500. -```text -RTRV-EQPT::ALL:100; -RTRV-ALM-ALL::ALL:101; -RTRV-SW-VER:::102; -``` - -## TL1 is not a CLI - -There is no enable mode, no pager to turn off, and no configuration save step, so these templates -leave all three empty. Login is in-band: the node opens on a bare `<` prompt and waits for an -`ACT-USER` command, which rConfig sends itself. Every command is terminated by `;` and correlated -by a CTAG that the node echoes back. +## The password quoting quirk -Passwords are always sent quoted. A 6500 rejects a complex password sent bare, and quoting also -keeps a password containing `:` — the TL1 field separator — from mis-framing the command. +A 6500 rejects a complex password sent bare, which is what prompted rConfig to quote TL1 passwords +in the first place. rConfig now quotes on every vendor, so this is history rather than +configuration, but it is the reason the behaviour exists. -## Gateway and remote NEs +## Neighbour discovery -Optical networks are reached through a **Gateway NE (GNE)**, the node you actually connect to, -which fronts **Remote NEs (RNEs)** that have no management access of their own. Set -`tl1Gateway: "on"` on the GNE's template and rConfig runs `tl1NeighbourCmd` after collecting it, -discovers the RNEs behind it, and creates a device record for each one. RNEs are then collected -by addressing their TID in-band over a session to the GNE. +A 6500 answers `RTRV-NE-LIST` with one quoted record per remote NE: -An RNE can be **dual-homed** — reachable through two or more GNEs. rConfig identifies an RNE by -its TID, so an RNE reported by a second gateway gains a second path rather than a duplicate device -record. One gateway is the primary; if a session through it cannot be established, the collection -falls over to another. - -## Connection limits +```text +"SHELF-1::SID=\"RNE-LIMERICK\",NENAME=\"RNE-LIMERICK\",GNE=NO,GNEIPADDR=,INETADDR=10.0.254.3,COST=30,NETYPE=00011600" +``` -Every RNE collection opens its **own** session to the gateway. A GNE fronting a hundred RNEs would -otherwise see a hundred sessions attempted as fast as the queue can run them, and a node that -refuses connections past its own cap fails whichever collections lose that race. +`RTRV-NODES` reports the same set under different field names (`TID=`, `REMOTESHELF`, `IPADDR`, +`MEMBER`, `SITEID`) and rConfig parses either, so a template may use whichever a given release +answers. -`tl1MaxConnections` caps how many sessions rConfig opens to one gateway at a time. It defaults to -`20` and belongs on the **GNE's** template — RNEs inherit their gateway's limit rather than -carrying one of their own. +`INETADDR` is the RNE's own management address, so discovered RNEs show their own IP rather than +the gateway's. `GNE=YES` marks a neighbour that is itself a gateway. -```yaml -connect: - tl1Gateway: "on" - tl1MaxConnections: 20 -``` +A 6500 echoes the addressed TID in the response header, so rConfig can confirm a routed reply came +from the RNE rather than from the gateway answering as itself. Not every vendor does this. -A collection that finds no free slot is not a failure: nothing was dialled, so the device is not -marked unreachable and no failure notification is sent. It waits and retries, giving up after an -hour. A dual-homed RNE whose primary gateway is at capacity will use its other gateway instead of -waiting. +## Terminology -Set it to what the node itself will accept. Too high and the node refuses connections; too low and -a large gateway takes longer to work through its RNEs. Values outside 1 to 500 are clamped, and -anything non-numeric falls back to the default, so a typo cannot stop a gateway collecting. +Ciena calls the elements behind a gateway **RNEs** (Remote NEs). Cisco calls them ENEs and +Infinera calls them remote nodes. They are the same idea, and rConfig's UI uses Ciena's term. See [docs/TEMPLATES.md](../docs/TEMPLATES.md) for what each key means and [docs/CONTRIBUTING.md](../docs/CONTRIBUTING.md) before submitting a change. diff --git a/ciena/ciena-6500-tl1-ssh.yml b/ciena/ciena-6500-tl1-ssh.yml index 01ac1ad..d7dd97a 100644 --- a/ciena/ciena-6500-tl1-ssh.yml +++ b/ciena/ciena-6500-tl1-ssh.yml @@ -16,6 +16,6 @@ connect: protocol: tl1 # Connection protocol: 'ssh', 'telnet', 'script' or 'tl1' port: 22000 # Port number (range: 1-65535) sshAuth: password # SSH transport auth: 'password' (SSH+TL1) or 'none' (TL1-only) - tl1Gateway: "on" # GNE only: discover RNEs behind this node via RTRV-NBR ('on'/'off') - tl1NeighbourCmd: "RTRV-NBR:ALL" # Neighbour-discovery command (TID/AID composable) + tl1Vendor: ciena # TL1 dialect: sets the neighbour command and record format + tl1Gateway: "on" # GNE only: discover the RNEs behind this node ('on'/'off') tl1MaxConnections: 20 # GNE only: max concurrent TL1 sessions rConfig opens to this node diff --git a/ciena/ciena-6500-tl1-telnet.yml b/ciena/ciena-6500-tl1-telnet.yml index 08d7165..7c3b5d1 100644 --- a/ciena/ciena-6500-tl1-telnet.yml +++ b/ciena/ciena-6500-tl1-telnet.yml @@ -17,6 +17,6 @@ connect: tl1Transport: telnet # TL1 byte transport: 'ssh' (default) | 'telnet' port: 23000 # Raw-TCP TL1 port (range: 1-65535) sshAuth: none # Ignored when tl1Transport: telnet (no transport auth) - tl1Gateway: "on" # GNE only: discover RNEs behind this node via RTRV-NBR ('on'/'off') - tl1NeighbourCmd: "RTRV-NBR:ALL" # Neighbour-discovery command (TID/AID composable) + tl1Vendor: ciena # TL1 dialect: sets the neighbour command and record format + tl1Gateway: "on" # GNE only: discover the RNEs behind this node ('on'/'off') tl1MaxConnections: 20 # GNE only: max concurrent TL1 sessions rConfig opens to this node diff --git a/cisco/README.md b/cisco/README.md index 5e32b30..92d89c2 100644 --- a/cisco/README.md +++ b/cisco/README.md @@ -1,14 +1,66 @@ -# Cisco Cisco 1120 FTD firewalls -You may use the standard Cisco IOS SSH Template for these devices, BUT when configuring the device within the rConfig UI, please use the following as a prompt for the device. '>' -A single qupte, greater than and single quote. This will ensure you get a full backup. +# Cisco -# Cisco WLC Controllers -There are known problems with scripts and automation software connecting to Cisco WLC Controllers due to their implementation of SSH/ Telnet protocols in their software. +The largest directory in the library, and now a mixed-edition one: the IOS, ASA, SMB and WLC +templates run on Core and Pro, and the two ONS 15454 TL1 templates are Pro only. That is the same +rule every other directory follows, which is that a template lives with its hardware. See +[docs/EDITIONS.md](../docs/EDITIONS.md). -> You may only use the cisco-wlc-ssh-noenable.yml template in this repository. +| Template | Use for | Edition | +| --- | --- | --- | +| `cisco-ios-ssh-enable.yml` | IOS / IOS-XE over SSH, enable password required | Core, Pro | +| `cisco-ios-ssh-noenable.yml` | IOS / IOS-XE over SSH, account already at privilege 15 | Core, Pro | +| `cisco-ios-telnet-enable.yml` | IOS / IOS-XE over telnet, enable password required | Core, Pro | +| `cisco-ios-telnet-enable-nousername.yml` | IOS / IOS-XE over telnet, password-only login with no username prompt | Core, Pro | +| `cisco-ios-telnet-noenable.yml` | IOS / IOS-XE over telnet, account already at privilege 15 | Core, Pro | +| `cisco-asa-ssh-enable.yml` | ASA firewalls over SSH | Core, Pro | +| `cisco-smb-telnet-noenable.yml` | Small Business switches (SG/SF series) over telnet | Core, Pro | +| `cisco-wlc-ssh-noenable.yml` | Wireless LAN Controllers, SSH only, see below | Core, Pro | +| `cisco-ons15454-tl1-ssh.yml` | ONS 15454 optical nodes, TL1 on the SSH channel | **Pro** | +| `cisco-ons15454-tl1-telnet.yml` | ONS 15454 optical nodes, TL1 over raw TCP | **Pro** | -> You may only use SSH, please configure your devices accordingly. +## ONS 15454 (TL1) -> You may not run the 'shwo run-config' command, as it takes far to long to print out. You may use the 'show run-config commands' instead for running configuration +> **Status: `untested-starter`.** These two templates and the parser behind them were built from +> the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 TL1 reference. **Nobody has run +> them against a real node.** Documented is better than invented and weaker than seen on hardware. +> If you run these, please report what happened so they can move to `community-tested`. -Related Cisco WLC Information: [https://quickview.cloudapps.cisco.com/quickview/bug/CSCve45024](https://quickview.cloudapps.cisco.com/quickview/bug/CSCve45024) +Read [docs/TL1.md](../docs/TL1.md) for what TL1 is and how gateways work. What is particular to an +ONS 15454: + +**Cisco calls the elements behind a gateway ENEs** (End NEs). Ciena calls them RNEs, and rConfig's +UI uses Ciena's term. + +**`RTRV-MAP-NETWORK` records are positional**, not keyword-based: + +```text +"172.20.222.225,TID-000,15454" + ,, +``` + +`NODENAME` is the TID. `PRODUCT` is the only place any TL1 vendor reports a real platform per +element, so discovered ENEs carry their own model rather than the gateway's. The vendor +documentation notes `PRODUCT` comes back as `UNKNOWN` for a node running a different software +version; rConfig does not store that as a model. + +**A gateway lists itself** in its own network map. rConfig drops that record, so the gateway is not +reconciled as an element behind itself. + +## FTD firewalls (1120 and similar) + +Use the standard Cisco IOS SSH template, but set the device's prompt in the rConfig UI to `'>'`: +a single quote, a greater-than, and a single quote. Without it the backup is truncated. + +## WLC controllers + +Cisco WLC controllers implement SSH and telnet in a way that breaks most automation. Three rules: + +- Use `cisco-wlc-ssh-noenable.yml`. No other template in this directory works. +- Use SSH. Telnet does not work reliably against these controllers. +- Do not run `show run-config`; it takes far too long to print. Use `show run-config commands` + instead for the running configuration. + +Background: [CSCve45024](https://quickview.cloudapps.cisco.com/quickview/bug/CSCve45024). + +See [docs/TEMPLATES.md](../docs/TEMPLATES.md) for what each key means and +[docs/CONTRIBUTING.md](../docs/CONTRIBUTING.md) before submitting a change. diff --git a/cisco/cisco-ons15454-tl1-ssh.yml b/cisco/cisco-ons15454-tl1-ssh.yml new file mode 100644 index 0000000..22b66e5 --- /dev/null +++ b/cisco/cisco-ons15454-tl1-ssh.yml @@ -0,0 +1,22 @@ +# rConfig connection template +## Edition: pro +## Status: untested-starter +## Tested-on: not yet run against hardware +## Docs: https://docs.rconfig.com/device-management/connection-templates/ +## Community: https://github.com/rconfig/rConfig-templates +## Note: all free-text values must be wrapped in double quotes " " +## Note: built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 TL1 +## reference, NOT from a session capture. See cisco/README.md before relying on it. + +main: + name: "Cisco ONS 15454 - TL1 over SSH" # Template name for Cisco ONS 15454 optical nodes + desc: "Cisco ONS 15454 optical node, TL1 in-band ACT-USER login over SSH" # Description for UI display + +connect: + timeout: 15 # Connection timeout (in seconds) + protocol: tl1 # Connection protocol: 'ssh', 'telnet', 'script' or 'tl1' + port: 22000 # Port number (range: 1-65535) + sshAuth: password # SSH transport auth: 'password' (SSH+TL1) or 'none' (TL1-only) + tl1Vendor: cisco-ons # TL1 dialect: sets the neighbour command and record format + tl1Gateway: "on" # Gateway only: discover the ENEs behind this node ('on'/'off') + tl1MaxConnections: 20 # Gateway only: max concurrent TL1 sessions rConfig opens to this node diff --git a/cisco/cisco-ons15454-tl1-telnet.yml b/cisco/cisco-ons15454-tl1-telnet.yml new file mode 100644 index 0000000..2d114e2 --- /dev/null +++ b/cisco/cisco-ons15454-tl1-telnet.yml @@ -0,0 +1,23 @@ +# rConfig connection template +## Edition: pro +## Status: untested-starter +## Tested-on: not yet run against hardware +## Docs: https://docs.rconfig.com/device-management/connection-templates/ +## Community: https://github.com/rconfig/rConfig-templates +## Note: all free-text values must be wrapped in double quotes " " +## Note: built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 TL1 +## reference, NOT from a session capture. See cisco/README.md before relying on it. + +main: + name: "Cisco ONS 15454 - TL1 over Telnet" # Template name for Cisco ONS 15454 optical nodes + desc: "Cisco ONS 15454 optical node, TL1 in-band ACT-USER login over telnet/raw-TCP" # Description for UI display + +connect: + timeout: 15 # Connection timeout (in seconds) + protocol: tl1 # Connection protocol: 'ssh', 'telnet', 'script' or 'tl1' + tl1Transport: telnet # TL1 byte transport: 'ssh' (default) | 'telnet' + port: 3083 # Raw-TCP TL1 port (range: 1-65535) + sshAuth: none # Ignored when tl1Transport: telnet (no transport auth) + tl1Vendor: cisco-ons # TL1 dialect: sets the neighbour command and record format + tl1Gateway: "on" # Gateway only: discover the ENEs behind this node ('on'/'off') + tl1MaxConnections: 20 # Gateway only: max concurrent TL1 sessions rConfig opens to this node diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index b95161f..12e9b8c 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -132,7 +132,7 @@ rather than the file. **No deprecated keys.** `pagerPrompt` and `pagerPromptCmd` are ignored by rConfig and must not appear. The validator treats them as errors. -**Only keys in the legend.** [TEMPLATES.md](TEMPLATES.md) lists all 47 keys across 7 sections. +**Only keys in the legend.** [TEMPLATES.md](TEMPLATES.md) lists all 48 keys across 7 sections. Anything else is an error, because a key rConfig does not read does nothing except mislead the next reader. If your device needs behaviour no existing key expresses, use the [new key request form](../.github/ISSUE_TEMPLATE/new-key-request.yml). That is a change to diff --git a/docs/EDITIONS.md b/docs/EDITIONS.md index 1458bb5..995f550 100644 --- a/docs/EDITIONS.md +++ b/docs/EDITIONS.md @@ -16,8 +16,10 @@ The simple version, which covers most people: - **Everything under `pro-features/` requires Pro.** That is the Script Integration Engine templates and scripts, the SSH private key template, and the xFTP inbound-only template. -One exception to the directory rule is called out below: the two TL1 templates live in `ciena/` -because they are Ciena device templates, but TL1 itself is Pro only. +The directory rule has no exceptions. TL1 templates are Pro only, and they live with their +vendor like everything else: `ciena/`, `infinera/`, `cisco/`. That makes `cisco/` a mixed-edition +directory, which is fine and deliberate. **Edition follows the capability a template uses, never +the directory it sits in.** ## Capability matrix @@ -26,19 +28,19 @@ because they are Ciena device templates, but TL1 itself is Pro only. | `protocol: ssh` | Yes | Yes | The bulk of the library | | `protocol: telnet` | Yes | Yes | | | `protocol: script` (Script Integration Engine) | No | Yes | Templates and example scripts live in `pro-features/sie/` | -| `protocol: tl1` | No | Yes | The two templates live in `ciena/` because they are Ciena device templates, but the protocol is Pro only | +| `protocol: tl1` | No | Yes | Templates live with their vendor (`ciena/`, `infinera/`, `cisco/`), so `cisco/` holds both Core and Pro templates. See [TL1.md](TL1.md) | | Inbound-only devices (`xftp` / `ftp`) | No | Yes | The device pushes its configuration in rather than rConfig connecting out. `xftp` is the canonical value from V8.3.2 onwards; `ftp` is the value on earlier releases and stays accepted. See [pro-features/xftp/README.md](../pro-features/xftp/README.md) | | Protocol fallback (`fallbackProtocol`, `fallbackPort`, `probeTimeout`) | No | Yes | Resolves which protocol a device actually answers on, then caches it. No shipped template uses these keys yet | | Prompt sync on login (`syncToPromptOnLogin`, `promptSyncTimeout`) | No | Yes | The fix for output appearing under the wrong command | | `auth.sshPrivKey` | **Not supported** | Yes | Code to read this key is present in Core, but private key authentication is supported on Pro only. This is a support position, not a code gate: it may appear to work in Core and is still not supported there. The template lives in `pro-features/ssh-private-key/` | -## The 13 Pro-only keys +## The 15 Pro-only keys -Of the 47 keys in [TEMPLATES.md](TEMPLATES.md), 14 are read only by Pro. +Of the 48 keys in [TEMPLATES.md](TEMPLATES.md), 15 are read only by Pro. | Section | Keys | | --- | --- | -| `connect`, TL1 | `sshAuth`, `tl1Transport`, `tl1Gateway`, `tl1NeighbourCmd`, `tl1MaxConnections` | +| `connect`, TL1 | `sshAuth`, `tl1Transport`, `tl1Vendor`, `tl1Gateway`, `tl1NeighbourCmd`, `tl1MaxConnections` | | `connect`, fallback | `fallbackProtocol`, `fallbackPort`, `probeTimeout` | | `connect`, script | `idletimeout` | | `config`, prompt sync | `syncToPromptOnLogin`, `promptSyncTimeout` | diff --git a/docs/TEMPLATES.md b/docs/TEMPLATES.md index 971ed34..bae43a2 100644 --- a/docs/TEMPLATES.md +++ b/docs/TEMPLATES.md @@ -150,8 +150,9 @@ Script templates never build a connection object, so neither key is read for `pr | `idletimeout` | int | seconds | Optional, default `30` | script | **Pro only** | All lowercase. `Script/ScriptConnectionManager.php:34` | | `sshAuth` | string | `none`, or anything else for password | Optional, default `password` | tl1 | **Pro only** | `none` skips transport authentication before the TL1 `ACT-USER` login. `TL1/Connect.php:70`, `Transport/SshTransport.php:33` | | `tl1Transport` | string | `telnet`, or anything else for ssh | Optional, default `ssh` | tl1 | **Pro only** | Anything that is not literally `telnet` falls back to SSH. `TL1/Connect.php:71`, `Transport/Tl1TransportFactory.php:15-20` | +| `tl1Vendor` | string | `ciena`, `infinera`, `cisco-ons` | Optional, default `ciena` | tl1 | **Pro only** | Selects the TL1 dialect: the neighbour-discovery verb, the record format it returns, the node's prompt, and whether a routed reply's header SID can be compared to the addressed TID. An unrecognised value fails the collection with a readable message rather than falling back to Ciena, because a typo collecting as the wrong vendor would parse nothing, report no elements, and flag every element behind that gateway as missing on the next run. See [TL1.md](TL1.md). `TL1/Connect.php`, `TL1/Vendor/Tl1VendorRegistry.php` | | `tl1Gateway` | boolean or string | `true`, `on`, `1`, `yes` | Optional, default `false` | tl1 | **Pro only** | The one key that accepts both a YAML boolean and the string forms, case-insensitively. Enables neighbour discovery. `TL1/Connect.php:93-95` | -| `tl1NeighbourCmd` | string | a TL1 command | Optional, default `RTRV-NBR:ALL` | tl1 | **Pro only** | Only used when `tl1Gateway` is on. `TL1/Connect.php:97` | +| `tl1NeighbourCmd` | string | a TL1 command | Optional, defaults to the vendor's own | tl1 | **Pro only** | Only used when `tl1Gateway` is on, and best left unset: each `tl1Vendor` supplies its own command (`RTRV-NE-LIST`, `RTRV-TIDMAP`, `RTRV-MAP-NETWORK`). Set it only to override the verb. A template naming the retired `RTRV-NBR` gets the vendor's command substituted, with a warning logged. `TL1/Connect.php` | | `tl1MaxConnections` | int | clamped to 1 to 500 | Optional, default `20` | tl1 | **Pro only** | Caps how many TL1 sessions rConfig opens to this gateway at once. Every RNE behind a GNE opens its own session, so without a cap a nightly run can open as many at one node as there are queue workers, and a node that refuses connections past its own limit fails the ones that lose the race. Collections that find no free slot wait and retry rather than failing, giving up after an hour. Values outside 1 to 500 are clamped, and anything non-numeric falls back to the default, so a typo cannot stop a gateway collecting. Set it on the GNE's template; RNEs inherit the gateway's limit. `TL1/Connect.php:108`, `TL1/Tl1GatewayConnections.php`, `TL1/Tl1ConnectionManager.php:38` | | `fallbackProtocol` | string | `ssh`, `telnet` | Optional, default none | dispatcher | **Pro only** | Undocumented before this legend. Set it to the other protocol and rConfig resolves which one the device actually answers on, caches the result, then dispatches normally. Only activates when it differs from `protocol` and both are ssh or telnet. `ProtocolFallbackConnectionManager.php:28,50-55,64` | | `fallbackPort` | int | 1 to 65535 | Optional, defaults to 22 for ssh or 23 for telnet | dispatcher | **Pro only** | Undocumented before this legend. Port used for the fallback attempt. A device port override still wins. `ProtocolFallbackConnectionManager.php:30,70-91` | @@ -370,10 +371,10 @@ This legend was compiled from a full read of the rConfig connection stack in bot | YAML parser | `symfony/yaml` v8.1.2 | | Evidence file | `legend-evidence.md` | -Coverage: 47 keys across 7 top-level sections. Core reads 33 of them, set out row by row in -[EDITIONS.md](EDITIONS.md). The 13 that are Pro only -are the four TL1 keys, the three fallback keys, `idletimeout`, `sshAuth`, `syncToPromptOnLogin`, -`promptSyncTimeout`, and the three `failure_criteria` keys. +Coverage: 48 keys across 7 top-level sections. Core reads 33 of them, set out row by row in +[EDITIONS.md](EDITIONS.md). The 15 that are Pro only are the four TL1 keys plus `tl1Vendor`, the +three fallback keys, `idletimeout`, `sshAuth`, `syncToPromptOnLogin`, `promptSyncTimeout`, and the +three `failure_criteria` keys. Line references point at the two codebases above. They are accurate as of those commits and will drift as the code changes. Re-verify against the evidence file before relying on a specific line. diff --git a/docs/TL1.md b/docs/TL1.md new file mode 100644 index 0000000..471bf79 --- /dev/null +++ b/docs/TL1.md @@ -0,0 +1,114 @@ +# TL1 + +TL1 (Telcordia GR-831) is how optical transport gear is managed. It is not a CLI, and treating it +as one is where most of the surprises come from. + +rConfig supports three TL1 platforms. Their templates live with their vendor, like every other +template in this library: `ciena/`, `infinera/`, `cisco/`. + +| Vendor | Templates | Status | +| --- | --- | --- | +| Ciena 6500 | [`ciena/`](../ciena/) | `community-tested` | +| Infinera DTN-X | [`infinera/`](../infinera/) | `community-tested` | +| Cisco ONS 15454 | [`cisco/`](../cisco/) | `untested-starter`, see [cisco/README.md](../cisco/README.md) | + +TL1 is a **Pro-only** protocol on every vendor. See [EDITIONS.md](EDITIONS.md). + +## What is the same everywhere + +**There is no enable mode, no pager to turn off, and no configuration save step**, so TL1 +templates leave all three empty. + +**Login is in-band.** The node opens on a bare prompt and waits for an `ACT-USER` command, which +rConfig sends itself. Whether the transport underneath authenticates first is the `sshAuth` key: +`password` for SSH auth then `ACT-USER`, `none` when `ACT-USER` is the only gate. + +**Every command is terminated by `;`** and correlated by a CTAG that the node echoes back. + +**Passwords are always sent quoted.** This started as a Ciena fix, and it is not Ciena-specific: +quoting keeps a password containing `:`, the TL1 field separator, from mis-framing the command on +any platform. + +**Gateways front elements that have no management access of their own.** You connect to the +gateway; the elements behind it are addressed in-band by putting their TID in the command. Set +`tl1Gateway: "on"` on the **gateway's** template and rConfig discovers them after each collection +and creates a device record for each one. + +An element can be **dual-homed**, reachable through two or more gateways. rConfig identifies an +element by its TID, so one reported by a second gateway gains a second path rather than a +duplicate device record. One gateway is primary; if a session through it cannot be established, +the collection falls over to another. + +Typical retrieval commands to attach in an rConfig Command Group: + +```text +RTRV-EQPT::ALL:100; +RTRV-ALM-ALL::ALL:101; +RTRV-SW-VER:::102; +``` + +## What differs by vendor, and why it matters + +`tl1Vendor` selects the dialect. It defaults to `ciena`, so a template written before there was +more than one vendor keeps working untouched. + +| | `ciena` | `infinera` | `cisco-ons` | +| --- | --- | --- | --- | +| Prompt | `<` | `>` | `<` | +| Elements called | RNEs | remote nodes | ENEs | +| Neighbour command | `RTRV-NE-LIST` | `RTRV-TIDMAP` | `RTRV-MAP-NETWORK` | +| Record format | keyword, quoted | keyword, empty AID | **positional** | +| Response | one block | **paged** | one block | + +Three things follow from that table. + +**The prompt differs.** Leave the device's Main Prompt blank in the UI and the dialect supplies +the right one. A `<` typed into an Infinera device's prompt field will hang the session until it +times out. + +**Infinera pages its answer.** One logical response arrives as several blocks with the prompt +written between them. rConfig reads to the end of the response rather than to the first prompt. +Nothing to configure; it matters because a client that gets this wrong does not merely truncate +the list, it leaves the remaining blocks on the wire where they are read as the reply to the next +command. + +**Cisco reports each element's own address and model.** The other two do not, so their elements +show the gateway's address as a placeholder. + +## Connection limits + +Every element collection opens its **own** session to the gateway. A gateway fronting a hundred +elements would otherwise see a hundred sessions attempted as fast as the queue can run them, and a +node that refuses connections past its own cap fails whichever collections lose that race. + +`tl1MaxConnections` caps how many sessions rConfig opens to one gateway at a time. It defaults to +`20` and belongs on the **gateway's** template; elements inherit their gateway's limit rather than +carrying one of their own. + +```yaml +connect: + tl1Vendor: ciena + tl1Gateway: "on" + tl1MaxConnections: 20 +``` + +A collection that finds no free slot is not a failure: nothing was dialled, so the device is not +marked unreachable and no failure notification is sent. It waits and retries, giving up after an +hour. A dual-homed element whose primary gateway is at capacity uses its other gateway instead of +waiting. + +Set it to what the node itself will accept. Too high and the node refuses connections; too low and +a large gateway takes longer to work through its elements. Values outside 1 to 500 are clamped, +and anything non-numeric falls back to the default, so a typo cannot stop a gateway collecting. + +## `tl1NeighbourCmd` + +Optional, and best left out. Each vendor's own command is the default. Set it only to override the +verb, for example to pass an AID a particular node needs. + +Templates predating multi-vendor support named `RTRV-NBR`, which no shipped node answers. rConfig +substitutes the vendor's real command and logs a warning rather than discovering nothing. Update +the template when you see that warning. + +See [TEMPLATES.md](TEMPLATES.md) for what each key means and [CONTRIBUTING.md](CONTRIBUTING.md) +before submitting a change. diff --git a/infinera/README.md b/infinera/README.md new file mode 100644 index 0000000..a9e3b2f --- /dev/null +++ b/infinera/README.md @@ -0,0 +1,53 @@ +# Infinera + +Covers Infinera DTN-X optical nodes, managed over TL1 rather than a conventional CLI. + +| Template | Use for | +| --- | --- | +| `infinera-dtnx-tl1-ssh.yml` | DTN-X nodes reached over SSH, TL1 carried on the SSH channel | +| `infinera-dtnx-tl1-telnet.yml` | DTN-X nodes reached over raw TCP on a TL1 port, typically 3082/3083 | + +**Read [docs/TL1.md](../docs/TL1.md) first.** It covers what TL1 is, in-band `ACT-USER` login, +gateways and dual-homed elements, and `tl1MaxConnections`. What follows is only what is particular +to a DTN-X, and two of these three items will bite anyone assuming Ciena's behaviour. + +## The prompt is `>` + +Not `<`. **Leave the device's Main Prompt blank in the rConfig UI** and the dialect supplies the +right one. A `<` typed in there will hang the session until it times out. + +## The response is paged + +`RTRV-TIDMAP` returns one logical answer as several blocks: every block but the last is coded +`RTRV` rather than `COMPLD`, with the prompt written between them. + +rConfig reads to the end of the response rather than to the first prompt, so there is nothing to +configure. It is worth knowing because the failure mode is not a truncated list. A client that +stops at the first prompt leaves the remaining blocks in the socket, where they are read back as +the reply to the *next* command, and every command after that is answered out of step. + +## The response header carries the system name, not the TID + +A DTN-X relaying a command for another node still answers under its own system name: + +```text + LXTNKYXAO4Z 26-09-12 19:53:38 +M 3 COMPLD +``` + +even when the command addressed `STLTND1Y`. So a routed reply cannot be confirmed by comparing the +header to the TID, the way it can on a 6500. rConfig knows this and does not apply that check to +this platform. Do not "fix" it. + +## Records + +```text +"::TID=CSVLTNFCO1Y,NODEID=MA4623110007,ROUTERID=11.253.152.33" +``` + +Keyword fields with an empty AID. `ROUTERID` is a routing identifier despite being shaped like an +address, so rConfig does not store it as the node's management IP: discovered nodes show their +gateway's address instead. + +See [docs/TEMPLATES.md](../docs/TEMPLATES.md) for what each key means and +[docs/CONTRIBUTING.md](../docs/CONTRIBUTING.md) before submitting a change. diff --git a/infinera/infinera-dtnx-tl1-ssh.yml b/infinera/infinera-dtnx-tl1-ssh.yml new file mode 100644 index 0000000..a5674bc --- /dev/null +++ b/infinera/infinera-dtnx-tl1-ssh.yml @@ -0,0 +1,20 @@ +# rConfig connection template +## Edition: pro +## Status: community-tested +## Tested-on: rConfig V8 Pro +## Docs: https://docs.rconfig.com/device-management/connection-templates/ +## Community: https://github.com/rconfig/rConfig-templates +## Note: all free-text values must be wrapped in double quotes " " + +main: + name: "Infinera DTN-X - TL1 over SSH" # Template name for Infinera DTN-X nodes + desc: "Infinera DTN-X optical node, TL1 in-band ACT-USER login over SSH" # Description for UI display + +connect: + timeout: 15 # Connection timeout (in seconds) + protocol: tl1 # Connection protocol: 'ssh', 'telnet', 'script' or 'tl1' + port: 22000 # Port number (range: 1-65535) + sshAuth: password # SSH transport auth: 'password' (SSH+TL1) or 'none' (TL1-only) + tl1Vendor: infinera # TL1 dialect: sets the neighbour command and record format + tl1Gateway: "on" # Gateway only: discover the nodes behind this one ('on'/'off') + tl1MaxConnections: 20 # Gateway only: max concurrent TL1 sessions rConfig opens to this node diff --git a/infinera/infinera-dtnx-tl1-telnet.yml b/infinera/infinera-dtnx-tl1-telnet.yml new file mode 100644 index 0000000..32edded --- /dev/null +++ b/infinera/infinera-dtnx-tl1-telnet.yml @@ -0,0 +1,21 @@ +# rConfig connection template +## Edition: pro +## Status: community-tested +## Tested-on: rConfig V8 Pro +## Docs: https://docs.rconfig.com/device-management/connection-templates/ +## Community: https://github.com/rconfig/rConfig-templates +## Note: all free-text values must be wrapped in double quotes " " + +main: + name: "Infinera DTN-X - TL1 over Telnet" # Template name for Infinera DTN-X nodes + desc: "Infinera DTN-X optical node, TL1 in-band ACT-USER login over telnet/raw-TCP" # Description for UI display + +connect: + timeout: 15 # Connection timeout (in seconds) + protocol: tl1 # Connection protocol: 'ssh', 'telnet', 'script' or 'tl1' + tl1Transport: telnet # TL1 byte transport: 'ssh' (default) | 'telnet' + port: 3082 # Raw-TCP TL1 port (range: 1-65535) + sshAuth: none # Ignored when tl1Transport: telnet (no transport auth) + tl1Vendor: infinera # TL1 dialect: sets the neighbour command and record format + tl1Gateway: "on" # Gateway only: discover the nodes behind this one ('on'/'off') + tl1MaxConnections: 20 # Gateway only: max concurrent TL1 sessions rConfig opens to this node diff --git a/pro-features/README.md b/pro-features/README.md index 5a52e43..5be0b89 100644 --- a/pro-features/README.md +++ b/pro-features/README.md @@ -9,9 +9,10 @@ repository root run on both Core and Pro. | [ssh-private-key/](ssh-private-key/) | SSH private key authentication | Authenticates with a key from the device credential record rather than a password | | [xftp/](xftp/) | Inbound-only devices | Marks a device that pushes its configuration into rConfig. rConfig never connects out to it. See [xftp/README.md](xftp/README.md) for the transports, file matching rules and device-side push commands | -One Pro capability does not live here. **TL1 templates are Pro only but sit in -[ciena/](../ciena/)**, because they are Ciena device templates and belong with their vendor. The -protocol is Pro; the directory placement follows the hardware. +One Pro capability does not live here. **TL1 templates are Pro only but sit with their vendor**, +in [ciena/](../ciena/), [infinera/](../infinera/) and [cisco/](../cisco/), because they are device +templates and belong with the hardware. Edition follows the capability a template uses, not the +directory it sits in. See [docs/TL1.md](../docs/TL1.md). For the full Core and Pro breakdown, including which individual template keys each edition reads, see [docs/EDITIONS.md](../docs/EDITIONS.md). diff --git a/scripts/validate_templates.py b/scripts/validate_templates.py index 0c32714..6a41ed4 100644 --- a/scripts/validate_templates.py +++ b/scripts/validate_templates.py @@ -51,14 +51,15 @@ class RConfigLoader(yaml.SafeLoader): NEW_KEY_PROCESS = "see 'Requesting a new key' in " + LEGEND # --------------------------------------------------------------------------- -# The legend: 47 keys across 7 sections, from docs/TEMPLATES.md +# The legend: 48 keys across 7 sections, from docs/TEMPLATES.md # --------------------------------------------------------------------------- ALLOWED = { "main": {"name", "desc"}, "connect": { "protocol", "port", "timeout", "isNonInteractiveMode", "idletimeout", - "sshAuth", "tl1Transport", "tl1Gateway", "tl1NeighbourCmd", "tl1MaxConnections", + "sshAuth", "tl1Transport", "tl1Vendor", "tl1Gateway", "tl1NeighbourCmd", + "tl1MaxConnections", "fallbackProtocol", "fallbackPort", "probeTimeout", "kexOverride", "kexAlgorithms", }, @@ -114,6 +115,10 @@ class RConfigLoader(yaml.SafeLoader): DOCS_DEFAULT = "https://docs.rconfig.com/device-management/connection-templates/" COMMUNITY = "https://github.com/rconfig/rConfig-templates" +# Directories whose contents are not vendor templates, so the "filename starts with the +# directory name" rule does not apply to them. +FILENAME_PREFIX_EXEMPT = {"_base", "docs", "scripts"} + # Filenames that predate the convention and are handled in a later phase. FILENAME_EXCEPTIONS = { "_base/base.yml", @@ -280,6 +285,15 @@ def check_filename(rel, rep): if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*\.yml$", base): rep.error(rel, f"filename '{base}' is not lowercase-hyphenated, see CLAUDE.md") + # A vendor template must be named for the directory it sits in. Cheap insurance now + # that one protocol spans several vendor directories: a Ciena template dropped into + # cisco/ still parses, still validates, and is findable by nobody. Every file in the + # library already satisfies this, so it costs nothing to hold the line. + parts = rel.split("/") + if len(parts) == 2 and parts[0] not in FILENAME_PREFIX_EXEMPT: + if not base.startswith(parts[0] + "-"): + rep.error(rel, f"filename '{base}' does not start with its directory '{parts[0]}-'") + def main(): quiet = "--quiet" in sys.argv From 9845f9488675a799f6ba0590b480d89422528f3f Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Sun, 13 Sep 2026 06:42:52 +0100 Subject: [PATCH 2/3] docs(tl1): state the RTRV-NBR override in every vendor README and the registry tl1NeighbourCmd is still fully configurable: set it and rConfig sends exactly what you wrote. The shipped templates simply stop setting it, so the default comes from tl1Vendor. The exception was documented only in docs/TEMPLATES.md and docs/TL1.md, and it deserves to be stated wherever someone configures a TL1 device. A value beginning with RTRV-NBR is replaced with the vendor's own command and a warning is logged, because that verb was the shipped default before 8.4.0 and came from rConfig's own simulator rather than from hardware. Each vendor README now carries the same section, naming that vendor's command, and says plainly that this is the one place a deliberately set key is overridden, with a route to get the special case removed if someone has a node that genuinely answers RTRV-NBR. Co-Authored-By: Claude Opus 5 (1M context) --- ciena/README.md | 21 +++++++++++++++++++-- cisco/README.md | 19 +++++++++++++++++-- docs/TEMPLATES.md | 2 +- docs/TL1.md | 9 ++++++--- infinera/README.md | 25 +++++++++++++++++++++---- 5 files changed, 64 insertions(+), 12 deletions(-) diff --git a/ciena/README.md b/ciena/README.md index 3ed307b..db97454 100644 --- a/ciena/README.md +++ b/ciena/README.md @@ -21,9 +21,9 @@ configuration, but it is the reason the behaviour exists. A 6500 answers `RTRV-NE-LIST` with one quoted record per remote NE: -```text +``text "SHELF-1::SID=\"RNE-LIMERICK\",NENAME=\"RNE-LIMERICK\",GNE=NO,GNEIPADDR=,INETADDR=10.0.254.3,COST=30,NETYPE=00011600" -``` +`` `RTRV-NODES` reports the same set under different field names (`TID=`, `REMOTESHELF`, `IPADDR`, `MEMBER`, `SITEID`) and rConfig parses either, so a template may use whichever a given release @@ -35,6 +35,23 @@ the gateway's. `GNE=YES` marks a neighbour that is itself a gateway. A 6500 echoes the addressed TID in the response header, so rConfig can confirm a routed reply came from the RNE rather than from the gateway answering as itself. Not every vendor does this. +## `tl1NeighbourCmd` + +Optional. Leave it unset and `tl1Vendor: ciena` supplies `RTRV-NE-LIST`. Set it to send a +different verb, for example to pass an AID a particular node needs, and rConfig sends exactly +what you wrote. + +**One value is not honoured.** A command beginning with `RTRV-NBR` is replaced with `RTRV-NE-LIST` +and a warning is written to the activity log. rConfig shipped `RTRV-NBR:ALL` as the default +before 8.4.0, and that verb and its payload format came from rConfig's own simulator rather than +from hardware, so honouring it means discovering nothing at all. The substitution exists so an +estate upgrading from an older release keeps collecting while its templates are updated. + +This is the one place rConfig overrides a value you set deliberately. If you have a node that +genuinely answers `RTRV-NBR`, say so on the issue tracker and the special case will be removed. + +--- + ## Terminology Ciena calls the elements behind a gateway **RNEs** (Remote NEs). Cisco calls them ENEs and diff --git a/cisco/README.md b/cisco/README.md index 92d89c2..38294f8 100644 --- a/cisco/README.md +++ b/cisco/README.md @@ -33,10 +33,10 @@ UI uses Ciena's term. **`RTRV-MAP-NETWORK` records are positional**, not keyword-based: -```text +``text "172.20.222.225,TID-000,15454" ,, -``` +`` `NODENAME` is the TID. `PRODUCT` is the only place any TL1 vendor reports a real platform per element, so discovered ENEs carry their own model rather than the gateway's. The vendor @@ -46,6 +46,21 @@ version; rConfig does not store that as a model. **A gateway lists itself** in its own network map. rConfig drops that record, so the gateway is not reconciled as an element behind itself. +### `tl1NeighbourCmd` + +Optional. Leave it unset and `tl1Vendor: cisco-ons` supplies `RTRV-MAP-NETWORK`. Set it to send a +different verb, for example to pass an AID a particular node needs, and rConfig sends exactly +what you wrote. + +**One value is not honoured.** A command beginning with `RTRV-NBR` is replaced with `RTRV-MAP-NETWORK` +and a warning is written to the activity log. rConfig shipped `RTRV-NBR:ALL` as the default +before 8.4.0, and that verb and its payload format came from rConfig's own simulator rather than +from hardware, so honouring it means discovering nothing at all. The substitution exists so an +estate upgrading from an older release keeps collecting while its templates are updated. + +This is the one place rConfig overrides a value you set deliberately. If you have a node that +genuinely answers `RTRV-NBR`, say so on the issue tracker and the special case will be removed. + ## FTD firewalls (1120 and similar) Use the standard Cisco IOS SSH template, but set the device's prompt in the rConfig UI to `'>'`: diff --git a/docs/TEMPLATES.md b/docs/TEMPLATES.md index bae43a2..23d349f 100644 --- a/docs/TEMPLATES.md +++ b/docs/TEMPLATES.md @@ -152,7 +152,7 @@ Script templates never build a connection object, so neither key is read for `pr | `tl1Transport` | string | `telnet`, or anything else for ssh | Optional, default `ssh` | tl1 | **Pro only** | Anything that is not literally `telnet` falls back to SSH. `TL1/Connect.php:71`, `Transport/Tl1TransportFactory.php:15-20` | | `tl1Vendor` | string | `ciena`, `infinera`, `cisco-ons` | Optional, default `ciena` | tl1 | **Pro only** | Selects the TL1 dialect: the neighbour-discovery verb, the record format it returns, the node's prompt, and whether a routed reply's header SID can be compared to the addressed TID. An unrecognised value fails the collection with a readable message rather than falling back to Ciena, because a typo collecting as the wrong vendor would parse nothing, report no elements, and flag every element behind that gateway as missing on the next run. See [TL1.md](TL1.md). `TL1/Connect.php`, `TL1/Vendor/Tl1VendorRegistry.php` | | `tl1Gateway` | boolean or string | `true`, `on`, `1`, `yes` | Optional, default `false` | tl1 | **Pro only** | The one key that accepts both a YAML boolean and the string forms, case-insensitively. Enables neighbour discovery. `TL1/Connect.php:93-95` | -| `tl1NeighbourCmd` | string | a TL1 command | Optional, defaults to the vendor's own | tl1 | **Pro only** | Only used when `tl1Gateway` is on, and best left unset: each `tl1Vendor` supplies its own command (`RTRV-NE-LIST`, `RTRV-TIDMAP`, `RTRV-MAP-NETWORK`). Set it only to override the verb. A template naming the retired `RTRV-NBR` gets the vendor's command substituted, with a warning logged. `TL1/Connect.php` | +| `tl1NeighbourCmd` | string | a TL1 command | Optional, defaults to the vendor's own | tl1 | **Pro only** | Only used when `tl1Gateway` is on, and best left unset: each `tl1Vendor` supplies its own command (`RTRV-NE-LIST`, `RTRV-TIDMAP`, `RTRV-MAP-NETWORK`). Set it only to override the verb, and rConfig sends exactly what you wrote. **One exception:** a value beginning with `RTRV-NBR` is replaced with the vendor's own command and a warning is logged. `RTRV-NBR:ALL` was the shipped default before 8.4.0, and that verb came from rConfig's simulator rather than from hardware, so honouring it discovers nothing. This is the only place a deliberately set key is overridden; each vendor README says so too. `TL1/Connect.php` | | `tl1MaxConnections` | int | clamped to 1 to 500 | Optional, default `20` | tl1 | **Pro only** | Caps how many TL1 sessions rConfig opens to this gateway at once. Every RNE behind a GNE opens its own session, so without a cap a nightly run can open as many at one node as there are queue workers, and a node that refuses connections past its own limit fails the ones that lose the race. Collections that find no free slot wait and retry rather than failing, giving up after an hour. Values outside 1 to 500 are clamped, and anything non-numeric falls back to the default, so a typo cannot stop a gateway collecting. Set it on the GNE's template; RNEs inherit the gateway's limit. `TL1/Connect.php:108`, `TL1/Tl1GatewayConnections.php`, `TL1/Tl1ConnectionManager.php:38` | | `fallbackProtocol` | string | `ssh`, `telnet` | Optional, default none | dispatcher | **Pro only** | Undocumented before this legend. Set it to the other protocol and rConfig resolves which one the device actually answers on, caches the result, then dispatches normally. Only activates when it differs from `protocol` and both are ssh or telnet. `ProtocolFallbackConnectionManager.php:28,50-55,64` | | `fallbackPort` | int | 1 to 65535 | Optional, defaults to 22 for ssh or 23 for telnet | dispatcher | **Pro only** | Undocumented before this legend. Port used for the fallback attempt. A device port override still wins. `ProtocolFallbackConnectionManager.php:30,70-91` | diff --git a/docs/TL1.md b/docs/TL1.md index 471bf79..b268270 100644 --- a/docs/TL1.md +++ b/docs/TL1.md @@ -106,9 +106,12 @@ and anything non-numeric falls back to the default, so a typo cannot stop a gate Optional, and best left out. Each vendor's own command is the default. Set it only to override the verb, for example to pass an AID a particular node needs. -Templates predating multi-vendor support named `RTRV-NBR`, which no shipped node answers. rConfig -substitutes the vendor's real command and logs a warning rather than discovering nothing. Update -the template when you see that warning. +Set it and rConfig sends exactly what you wrote, with one exception. A value beginning with +`RTRV-NBR` is replaced with the vendor's own command and a warning is logged. That verb was the +shipped default before 8.4.0 and came from rConfig's own simulator rather than from hardware, so +honouring it means discovering nothing. It is the only place a deliberately set key is overridden, +and it exists so an estate upgrading from an older release keeps collecting while its templates are +updated. Update the template when you see the warning. See [TEMPLATES.md](TEMPLATES.md) for what each key means and [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a change. diff --git a/infinera/README.md b/infinera/README.md index a9e3b2f..0be5ef4 100644 --- a/infinera/README.md +++ b/infinera/README.md @@ -30,20 +30,37 @@ the reply to the *next* command, and every command after that is answered out of A DTN-X relaying a command for another node still answers under its own system name: -```text +``text LXTNKYXAO4Z 26-09-12 19:53:38 M 3 COMPLD -``` +`` even when the command addressed `STLTND1Y`. So a routed reply cannot be confirmed by comparing the header to the TID, the way it can on a 6500. rConfig knows this and does not apply that check to this platform. Do not "fix" it. +## `tl1NeighbourCmd` + +Optional. Leave it unset and `tl1Vendor: infinera` supplies `RTRV-TIDMAP`. Set it to send a +different verb, for example to pass an AID a particular node needs, and rConfig sends exactly +what you wrote. + +**One value is not honoured.** A command beginning with `RTRV-NBR` is replaced with `RTRV-TIDMAP` +and a warning is written to the activity log. rConfig shipped `RTRV-NBR:ALL` as the default +before 8.4.0, and that verb and its payload format came from rConfig's own simulator rather than +from hardware, so honouring it means discovering nothing at all. The substitution exists so an +estate upgrading from an older release keeps collecting while its templates are updated. + +This is the one place rConfig overrides a value you set deliberately. If you have a node that +genuinely answers `RTRV-NBR`, say so on the issue tracker and the special case will be removed. + +--- + ## Records -```text +``text "::TID=CSVLTNFCO1Y,NODEID=MA4623110007,ROUTERID=11.253.152.33" -``` +`` Keyword fields with an empty AID. `ROUTERID` is a routing identifier despite being shaped like an address, so rConfig does not store it as the node's management IP: discovered nodes show their From 6e21267ff35887c2fe48fd92100b40bbc400f532 Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Sun, 13 Sep 2026 06:48:06 +0100 Subject: [PATCH 3/3] fix(cisco): put the untested caveat in vendor notes, not a second header field CI's apply_headers.py --check failed on both ONS 15454 templates. The standard header is a fixed schema, and "## Note:" is one of its fields, so my second "## Note:" line was dropped on rebuild and its continuation line left behind as an orphan that said nothing. The mechanism for per-template prose is a single-hash comment after the header, which the script preserves as a vendor note. hp/hp-procurve-telnet-noenable.yml is the existing example. The caveat now reads as three "# UNTESTED:" lines in that position, which is more prominent than the header field was anyway. Tested-on also changes from a phrase I invented to the library's standard "not yet tested, please file a template test report", matching every other untested-starter template. Both CI steps now pass locally, run exactly as the workflow runs them: apply_headers.py --check reports 0 changed, validate_templates.py 0 errors. Co-Authored-By: Claude Opus 5 (1M context) --- cisco/cisco-ons15454-tl1-ssh.yml | 7 ++++--- cisco/cisco-ons15454-tl1-telnet.yml | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cisco/cisco-ons15454-tl1-ssh.yml b/cisco/cisco-ons15454-tl1-ssh.yml index 22b66e5..0133d68 100644 --- a/cisco/cisco-ons15454-tl1-ssh.yml +++ b/cisco/cisco-ons15454-tl1-ssh.yml @@ -1,12 +1,13 @@ # rConfig connection template ## Edition: pro ## Status: untested-starter -## Tested-on: not yet run against hardware +## Tested-on: not yet tested, please file a template test report ## Docs: https://docs.rconfig.com/device-management/connection-templates/ ## Community: https://github.com/rconfig/rConfig-templates ## Note: all free-text values must be wrapped in double quotes " " -## Note: built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 TL1 -## reference, NOT from a session capture. See cisco/README.md before relying on it. +# UNTESTED: built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 +# TL1 reference, NOT from a session capture. Nobody has run this against a real node. +# Read cisco/README.md before relying on it, and please report what happens if you do. main: name: "Cisco ONS 15454 - TL1 over SSH" # Template name for Cisco ONS 15454 optical nodes diff --git a/cisco/cisco-ons15454-tl1-telnet.yml b/cisco/cisco-ons15454-tl1-telnet.yml index 2d114e2..e2ee654 100644 --- a/cisco/cisco-ons15454-tl1-telnet.yml +++ b/cisco/cisco-ons15454-tl1-telnet.yml @@ -1,12 +1,13 @@ # rConfig connection template ## Edition: pro ## Status: untested-starter -## Tested-on: not yet run against hardware +## Tested-on: not yet tested, please file a template test report ## Docs: https://docs.rconfig.com/device-management/connection-templates/ ## Community: https://github.com/rconfig/rConfig-templates ## Note: all free-text values must be wrapped in double quotes " " -## Note: built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 TL1 -## reference, NOT from a session capture. See cisco/README.md before relying on it. +# UNTESTED: built from the Cisco ONS SONET TL1 Command Guide R9.1 and Oracle's ONS 15454 +# TL1 reference, NOT from a session capture. Nobody has run this against a real node. +# Read cisco/README.md before relying on it, and please report what happens if you do. main: name: "Cisco ONS 15454 - TL1 over Telnet" # Template name for Cisco ONS 15454 optical nodes