netforge
Bidirectional converter between HP Comware and AlliedWare Plus network switch configurations.
Installation
pip install netforge
CLI usage
Single file
# HP Comware -> AlliedWare Plus
netforge switch.txt --to allied
# AlliedWare Plus -> HP Comware, write to file
netforge switch.txt --to hp --output out.txt
# Override auto-detection
netforge switch.txt --from hp --to allied
Batch (directory)
netforge configs/ --to allied --output converted/
All .txt and .cfg files in configs/ are converted. Results land in converted/.
stdin
cat switch.txt | netforge --to allied
ssh admin@switch "display current-configuration" | netforge --from hp --to allied
Detect vendor
netforge switch.txt --detect
# switch.txt: HP Comware (hp)
Report
netforge switch.txt --to allied --report
# prints IR summary (hostname, VLANs, interfaces, AAA schemes) to stderr
# converted config goes to stdout
Version
netforge --version
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Conversion / parsing error |
| 2 | Bad arguments / usage error |
| 3 | Vendor detection ambiguous or failed |
Python library
import netforge
# Auto-detect source vendor and convert
allied_config = netforge.convert(hp_config_text, to="allied")
hp_config = netforge.convert(allied_config_text, to="hp")
# Force source vendor
allied_config = netforge.convert(text, to="allied", from_vendor="hp")
# Detect only
vendor = netforge.detect_vendor(text) # "hp" or "allied"
Lower-level API
from netforge.parsers.hp import HPParser
from netforge.renderers.allied import AlliedRenderer
model = HPParser().parse(raw_text) # UniversalConfig (dataclass IR)
print(model.hostname, model.vlans)
output = AlliedRenderer().render(model)
Supported features
| Feature | HP Comware | AlliedWare Plus |
|---|---|---|
| Hostname | sysname |
hostname |
| VLANs | vlan <id> + name block |
vlan database |
| Access port | port access vlan <id> |
switchport access vlan <id> |
| Trunk port | port link-type trunk |
switchport mode trunk |
| SVI | interface Vlan-interface<id> |
interface vlan<id> |
| Interface name | GigabitEthernet1/0/1 |
port1.0.1 |
| Static routes | ip route-static |
ip route |
| RADIUS | named scheme block | radius-server host inline |
| TACACS+ | named scheme block | tacacs-server host inline |
| SSH | ssh server enable |
service ssh |
| NTP | ntp-service unicast-server |
ntp server |
| Syslog | info-center loghost |
log host |
| dot1x | dot1x per interface |
dot1x port-control auto |
| MAC auth | mac-authentication |
auth-mac enable |
| STP edge | stp edged-port |
spanning-tree edgeport |
| LLDP | lldp global enable |
lldp run |
| SNMP | snmp-agent |
snmp-server enable |
| DNS | dns server + dns domain |
ip name-server + ip domain-name |
| VTY lines | line vty + authentication-mode |
line vty + transport input |
| Local users | local-user + password hash |
username + password 8 |
Key placeholders
Encrypted secrets are never carried across vendors. The converter emits human-readable placeholders that the Key Manager can replace:
- TACACS / RADIUS keys:
<REPLACE_KEY_10_0_0_10> - User passwords:
<REPLACE_PASSWORD_admin>
Contributing
- Fork the repository and create a feature branch.
- Add your feature to the IR (
models.py), both parsers, both renderers. - Add fixture lines to
tests/fixtures/hp_sample.txtandallied_sample.txt. - Write tests in
tests/test_hp_parser.py,test_allied_parser.py,test_renderers.py. - Run
pytest tests/ -v— all tests must pass. - Open a pull request.
pip install -e ".[dev]"
pytest tests/ -v --tb=short
Changelog
See GitHub Releases for full history.
v1.1.0
- Fix hostname parsing on indented HP Comware configs
- Fix SSH, SNMP v3, static routes not converted
- Fix AAA duplicates and wrong suffixes
- Fix VTY lines format
- Add
no service http/no service telnetsystematically - Fix UnicodeEncodeError on Windows
License
MIT
Metadata
Release files for netforge 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| netforge-1.1.0.tar.gz | 86.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| netforge-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 116.1 kB
Release files / netforge-1.1.0.tar.gz
| Download URL | netforge-1.1.0.tar.gz |
|---|---|
| Size | 86.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
da4780f0368af2524775ef47e650ef73cf14eadd59e23656f98aeae11db8f865
|
|
BLAKE2b-256 checksum How to use checksums |
5998127702051573e941ac66cb6f7230142c553c97d32f14db5bea53ffb2b6c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / netforge-1.1.0-py3-none-any.whl
| Download URL | netforge-1.1.0-py3-none-any.whl |
|---|---|
| Size | 30.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
52a55ac9a9272e44c2d28395b0c2883163b3798b0ce482d5e7bff650b3ef78f0
|
|
BLAKE2b-256 checksum How to use checksums |
73cdca158905bf9916e9ade5690bcd99f977e60a60e982a9167fd93375380655
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|