CLI switches: a config-mode mixin for netgear_smart, tplink_jetstream and procurve #9

Open
opened 2026-10-06 17:31:29 +00:00 by christianmanivong · 1 comment
Owner

netgear_smart, tplink_jetstream and procurve all inherit ConfigLifecycleMixin, and each re-implements the same IOS-like config-mode mechanics around it.

Same code with different names or strings

  • commit_config: netgear_smart.py:1321 = tplink_jetstream.py:1084. procurve.py:1142 has the same skeleton.
  • rollback: netgear_smart.py:1355 = tplink_jetstream.py:1118.
  • _diff_to_commands: netgear_smart.py:1430 = tplink_jetstream.py:1219.
    • netgear's is a @staticmethod that hard-codes NetgearSmartDriver._parse_config_blocks/_negate_command, so a subclass cannot override them.
  • _parse_config_blocks: netgear_smart.py:1381 vs tplink_jetstream.py:1146. The block separator ("!" vs "#") and the block end ("exit" vs "exit"/"end") differ.
  • _negate_command: netgear_smart.py:1416 vs tplink_jetstream.py:1189. Same mechanism, different keyword table.
  • _apply_config_lines: netgear_smart.py:240, tplink_jetstream.py:215 and procurve.py:418. Comment characters and error regex differ.
  • _enter_config_mode ("configure") is identical three times (:219, :194, :393).
    • _exit_config_mode and _save_config differ only in the command: "exit"/"end", and "write memory"/"copy running-config startup-config".
  • Prompt regexes _any_prompt/_exec_prompt/_conf_prompt (:204–217, :185–192, :385–391) are nearly identical.
  • procurve._cli_set_vlan (procurve.py:854) and tplink.set_vlan (tplink_jetstream.py:1559) are identical. Both use the enter → apply → raise → exit → save wrapper, which appears about 10 times across the three drivers.
  • get_config (netgear_smart.py:847, tplink_jetstream.py:538) and set_poe (:1970, :1728) are the same template with dialect strings.

Shared gaps the copies have in common

  • Replace is a merge. commit_config uses _candidate_mode only to pick the exception class. A replace candidate is pushed additively, while compare_config shows a full diff.
  • Rollback ignores rejected lines. rollback discards the rejected-line result of _apply_config_lines (netgear_smart.py:1373, tplink_jetstream.py:1138).
  • procurve's rollback cannot undo additions. procurve inherits the base rollback, which re-stages the backup as a merge (config_lifecycle.py:106–115), so it cannot remove lines a commit added.

Proposal: CliConfigModeMixin(ConfigLifecycleMixin) in napalm_device_types/cli_config.py.

  • Concrete methods:
    • the prompts and enter/exit/save;
    • _apply_config_lines and _push_config(op, lines);
    • a commit_config template;
    • a block-diff rollback that reports rejected lines;
    • a get_config template.
  • Hooks:
    • the enter/exit/save commands;
    • _CONFIG_ERROR_RE and the comment characters;
    • block separators, block end and opener;
    • the negation tables;
    • _read_config, _strip_volatile.
  • Stays in the drivers: every show parser, the PoE/LAG/VLAN vocabulary, netgear's v7 detection and paging, and procurve's REST branches.

Prio P3: the largest block of shared code across the drivers (about 15 methods). New CLI switches would get it for free.

From the NetOrk function index (NetOrk/netork#670); every location was checked against the current code. Paths are relative to each driver repo.

`netgear_smart`, `tplink_jetstream` and `procurve` all inherit `ConfigLifecycleMixin`, and each re-implements the same IOS-like config-mode mechanics around it. **Same code with different names or strings** - `commit_config`: `netgear_smart.py`:1321 = `tplink_jetstream.py`:1084. `procurve.py`:1142 has the same skeleton. - `rollback`: `netgear_smart.py`:1355 = `tplink_jetstream.py`:1118. - `_diff_to_commands`: `netgear_smart.py`:1430 = `tplink_jetstream.py`:1219. - netgear's is a `@staticmethod` that hard-codes `NetgearSmartDriver._parse_config_blocks`/`_negate_command`, so a subclass cannot override them. - `_parse_config_blocks`: `netgear_smart.py`:1381 vs `tplink_jetstream.py`:1146. The block separator ("!" vs "#") and the block end ("exit" vs "exit"/"end") differ. - `_negate_command`: `netgear_smart.py`:1416 vs `tplink_jetstream.py`:1189. Same mechanism, different keyword table. - `_apply_config_lines`: `netgear_smart.py`:240, `tplink_jetstream.py`:215 and `procurve.py`:418. Comment characters and error regex differ. - `_enter_config_mode` ("configure") is identical three times (:219, :194, :393). - `_exit_config_mode` and `_save_config` differ only in the command: "exit"/"end", and "write memory"/"copy running-config startup-config". - Prompt regexes `_any_prompt`/`_exec_prompt`/`_conf_prompt` (:204–217, :185–192, :385–391) are nearly identical. - `procurve._cli_set_vlan` (`procurve.py`:854) and `tplink.set_vlan` (`tplink_jetstream.py`:1559) are identical. Both use the enter → apply → raise → exit → save wrapper, which appears about 10 times across the three drivers. - `get_config` (`netgear_smart.py`:847, `tplink_jetstream.py`:538) and `set_poe` (:1970, :1728) are the same template with dialect strings. **Shared gaps the copies have in common** - **Replace is a merge.** `commit_config` uses `_candidate_mode` only to pick the exception class. A replace candidate is pushed additively, while `compare_config` shows a full diff. - **Rollback ignores rejected lines.** `rollback` discards the rejected-line result of `_apply_config_lines` (`netgear_smart.py`:1373, `tplink_jetstream.py`:1138). - **procurve's rollback cannot undo additions.** procurve inherits the base `rollback`, which re-stages the backup as a merge (`config_lifecycle.py`:106–115), so it cannot remove lines a commit added. **Proposal:** `CliConfigModeMixin(ConfigLifecycleMixin)` in `napalm_device_types/cli_config.py`. - Concrete methods: - the prompts and enter/exit/save; - `_apply_config_lines` and `_push_config(op, lines)`; - a `commit_config` template; - a block-diff `rollback` that reports rejected lines; - a `get_config` template. - Hooks: - the enter/exit/save commands; - `_CONFIG_ERROR_RE` and the comment characters; - block separators, block end and opener; - the negation tables; - `_read_config`, `_strip_volatile`. - Stays in the drivers: every `show` parser, the PoE/LAG/VLAN vocabulary, netgear's v7 detection and paging, and procurve's REST branches. Prio P3: the largest block of shared code across the drivers (about 15 methods). New CLI switches would get it for free. From the NetOrk function index (NetOrk/netork#670); every location was checked against the current code. Paths are relative to each driver repo.
Author
Owner

Re-homed by docs/STRUCTURE.md (NAPALM/napalm-device-types#37, NetOrk/netork#1105): IOS-like config-mode mechanics are not agnostic, so they do not go here. A CLI-driver helper package, or left in the drivers.

Re-homed by `docs/STRUCTURE.md` (NAPALM/napalm-device-types#37, NetOrk/netork#1105): IOS-like config-mode mechanics are not agnostic, so they do not go here. A CLI-driver helper package, or left in the drivers.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NAPALM/napalm-device-types#9