simnos 2.0.0__tar.gz

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 (77) hide show
  1. simnos-2.0.0/PKG-INFO +151 -0
  2. simnos-2.0.0/README.md +119 -0
  3. simnos-2.0.0/pyproject.toml +152 -0
  4. simnos-2.0.0/simnos/__init__.py +11 -0
  5. simnos-2.0.0/simnos/core/__init__.py +0 -0
  6. simnos-2.0.0/simnos/core/host.py +97 -0
  7. simnos-2.0.0/simnos/core/nos.py +249 -0
  8. simnos-2.0.0/simnos/core/pydantic_models.py +198 -0
  9. simnos-2.0.0/simnos/core/servers.py +123 -0
  10. simnos-2.0.0/simnos/core/simnos.py +437 -0
  11. simnos-2.0.0/simnos/plugins/__init__.py +0 -0
  12. simnos-2.0.0/simnos/plugins/nos/__init__.py +37 -0
  13. simnos-2.0.0/simnos/plugins/nos/platforms_py/__init__.py +0 -0
  14. simnos-2.0.0/simnos/plugins/nos/platforms_py/arista_eos.py +139 -0
  15. simnos-2.0.0/simnos/plugins/nos/platforms_py/base_template.py +46 -0
  16. simnos-2.0.0/simnos/plugins/nos/platforms_py/cisco_ios.py +75 -0
  17. simnos-2.0.0/simnos/plugins/nos/platforms_py/configurations/arista_eos.yaml.j2 +0 -0
  18. simnos-2.0.0/simnos/plugins/nos/platforms_py/configurations/cisco_ios.yaml.j2 +0 -0
  19. simnos-2.0.0/simnos/plugins/nos/platforms_py/configurations/huawei_smartax.yaml.j2 +40 -0
  20. simnos-2.0.0/simnos/plugins/nos/platforms_py/huawei_smartax.py +123 -0
  21. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/arista_eos/show_clock.j2 +7 -0
  22. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/arista_eos/show_ip_int_br.j2 +7 -0
  23. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/arista_eos/show_running-config.j2 +84 -0
  24. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/arista_eos/show_version.j2 +17 -0
  25. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/cisco_ios/show_running-config.j2 +209 -0
  26. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/cisco_ios/show_version.j2 +63 -0
  27. simnos-2.0.0/simnos/plugins/nos/platforms_py/templates/huawei_smartax/display_board.j2 +7 -0
  28. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/alcatel_aos.yaml +30 -0
  29. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/alcatel_sros.yaml +653 -0
  30. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/allied_telesis_awplus.yaml +339 -0
  31. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/arista_eos.yaml +1540 -0
  32. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/aruba_os.yaml +176 -0
  33. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/avaya_ers.yaml +338 -0
  34. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/avaya_vsp.yaml +27 -0
  35. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/broadcom_icos.yaml +243 -0
  36. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/brocade_fastiron.yaml +859 -0
  37. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/brocade_netiron.yaml +563 -0
  38. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/checkpoint_gaia.yaml +208 -0
  39. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/ciena_saos.yaml +210 -0
  40. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/cisco_asa.yaml +1319 -0
  41. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/cisco_ftd.yaml +54 -0
  42. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/cisco_ios.yaml +4576 -0
  43. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/cisco_nxos.yaml +4769 -0
  44. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/cisco_s300.yaml +256 -0
  45. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/cisco_xr.yaml +6495 -0
  46. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/dell_force10.yaml +207 -0
  47. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/dell_powerconnect.yaml +133 -0
  48. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/dlink_ds.yaml +36 -0
  49. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/eltex.yaml +1230 -0
  50. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/ericsson_ipos.yaml +139 -0
  51. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/extreme_exos.yaml +351 -0
  52. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/fortinet.yaml +218 -0
  53. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/hp_comware.yaml +429 -0
  54. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/hp_procurve.yaml +516 -0
  55. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/huawei_smartax.yaml +415 -0
  56. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/huawei_vrp.yaml +589 -0
  57. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/ipinfusion_ocnos.yaml +68 -0
  58. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/juniper_junos.yaml +546 -0
  59. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/juniper_screenos.yaml +19 -0
  60. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/linux.yaml +85 -0
  61. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/mikrotik_routeros.yaml +259 -0
  62. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/paloalto_panos.yaml +331 -0
  63. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/ruckus_fastiron.yaml +636 -0
  64. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/ubiquiti_edgerouter.yaml +192 -0
  65. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/ubiquiti_edgeswitch.yaml +76 -0
  66. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/vyatta_vyos.yaml +85 -0
  67. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/yamaha.yaml +45 -0
  68. simnos-2.0.0/simnos/plugins/nos/platforms_yaml/zyxel_os.yaml +255 -0
  69. simnos-2.0.0/simnos/plugins/servers/__init__.py +12 -0
  70. simnos-2.0.0/simnos/plugins/servers/ssh_server_paramiko.py +518 -0
  71. simnos-2.0.0/simnos/plugins/servers/tap_io.py +40 -0
  72. simnos-2.0.0/simnos/plugins/servers/telnet_server.py +413 -0
  73. simnos-2.0.0/simnos/plugins/shell/__init__.py +7 -0
  74. simnos-2.0.0/simnos/plugins/shell/cmd_shell.py +196 -0
  75. simnos-2.0.0/simnos/plugins/shell/utils.py +63 -0
  76. simnos-2.0.0/simnos/plugins/utils/__init__.py +0 -0
  77. simnos-2.0.0/simnos/plugins/utils/cli.py +80 -0
simnos-2.0.0/PKG-INFO ADDED
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.3
2
+ Name: simnos
3
+ Version: 2.0.0
4
+ Summary: Simulated Network Operating System
5
+ Keywords: NetworkAutomation,Testing,SSH,Integration,NOS
6
+ Author: KeroRoute lab
7
+ License: MIT
8
+ Classifier: Intended Audience :: Telecommunications Industry
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Education
11
+ Classifier: Intended Audience :: Information Technology
12
+ Classifier: Intended Audience :: System Administrators
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Operating System :: Unix
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Topic :: Utilities
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: License :: OSI Approved :: MIT License
22
+ Requires-Dist: paramiko>=4.0,<5.0
23
+ Requires-Dist: pyyaml<7.0
24
+ Requires-Dist: pydantic<3.0
25
+ Requires-Dist: jinja2>=3.1.6
26
+ Requires-Dist: detect==2020.12.*
27
+ Maintainer: KeroRoute lab
28
+ Requires-Python: >=3.13, <3.15
29
+ Project-URL: Documentation, https://route-reflector.github.io/simnos/
30
+ Project-URL: Homepage, https://github.com/Route-Reflector/simnos/
31
+ Description-Content-Type: text/markdown
32
+
33
+ [English](README.md) | [日本語](README.ja.md)
34
+
35
+ [![Downloads][pepy-downloads-badge]][pepy-downloads-link]
36
+ [![PyPI][pypi-latest-release-badge]][pypi-latest-release-link]
37
+ [![PyPI versions][pypi-pyversion-badge]][pypi-pyversion-link]
38
+ [![GitHub Discussion][github-discussions-badge]][github-discussions-link]
39
+ [![Ruff][ruff-badge]][ruff-link]
40
+ [![Tests][github-tests-badge]][github-tests-link]
41
+
42
+ # Simulated Network Operating Systems - SIMNOS
43
+
44
+ > "Reality is merely an illusion, albeit a very persistent one."
45
+ >
46
+ > ~ Albert Einstein
47
+
48
+ SIMNOS simulates Network Operating Systems interactions. You can simulate
49
+ network devices like Cisco IOS or Huawei SmartAX interactions over
50
+ SSH with little effort. This project is mainly intended for testing
51
+ and development purposes.
52
+
53
+ [Documentation](https://route-reflector.github.io/simnos/) | [Examples](https://route-reflector.github.io/simnos/examples/) | [Platforms](https://route-reflector.github.io/simnos/platforms/)
54
+
55
+ ## Origin
56
+
57
+ SIMNOS is an independent project derived from [FakeNOS](https://github.com/fakenos/fakenos), created by Denis Mulyalin and maintained by Enric Perpinyà Pitarch. After significant divergence in tooling, platforms, and architecture, it was rebranded as SIMNOS to avoid confusion with the upstream project.
58
+
59
+ **AI Transparency:** AI-assisted development (Claude Code, Codex, Gemini, etc.) is actively used in this project. All AI-generated changes are reviewed by a human maintainer before merging.
60
+
61
+ **Key differences from FakeNOS:**
62
+
63
+ - Package name: `simnos` (on PyPI)
64
+ - Package manager: uv (migrated from Poetry)
65
+ - Linter/Formatter: Ruff (migrated from Black/Pylint)
66
+ - Python support: 3.13 / 3.14
67
+ - CI: Modernized GitHub Actions workflow
68
+ - NOS platforms: 5 additional platforms enabled (brocade_fastiron, ciena_saos, fortinet, juniper_screenos, ruckus_fastiron)
69
+ - Paramiko: upgraded to 4.0 with DH Group Exchange server-mode workaround
70
+
71
+ ## Why?
72
+
73
+ Crucial aspect of writing applications or scripts for Network Automation is
74
+ testing, often testing done using physical or virtual instances of network
75
+ appliances running certain version of Network Operating System (NOS). That
76
+ approach, while gives best integration results, in many cases carries a lot
77
+ of overhead to setup, run and tear down as well as putting significant burden
78
+ on compute and storage resource utilization.
79
+
80
+ Other approach is to mock underlying libraries methods to fool applications
81
+ under testing into believing that it is getting output from real devices. That
82
+ approach works very well for unit testing, but fails to simulate such aspects
83
+ as connection establishment and handling.
84
+
85
+ SIMNOS positions itself somewhere in the middle between full integration testing
86
+ and testing that mocks device interactions. SIMNOS allows to create NOS plugins
87
+ to produce pre-defined output to test applications behavior while running servers
88
+ to establish connections with.
89
+
90
+ ## What?
91
+
92
+ SIMNOS can:
93
+
94
+ - Run thousands of servers to stress test applications
95
+ - Simulate Network Operating Systems Command Line Interface (CLI) interactions
96
+ - Provide high-level API to create custom NOS plugins
97
+ - Run in docker container to simplify integration with your infrastructure
98
+ - Make use of SIMNOS CLI tool for quick run and prototype simulations
99
+ - Works on Windows, Mac and Linux under Python 3.13 and 3.14
100
+
101
+ ## How?
102
+
103
+ Send input and get the output - this is how we interact with many
104
+ Network Operating Systems, SIMNOS allows to pre-define the output
105
+ to sent in response to certain input commands, making it ideal for
106
+ isolated feature testing.
107
+
108
+ SIMNOS is a micro-kernel framework that can be extended using plugins.
109
+ The core is kept small and optimized while most of the functionality
110
+ offloaded to plugins.
111
+
112
+ SIMNOS has these pluggable systems:
113
+
114
+ - Server Plugins - plugins responsible for running various servers to connect with
115
+ - Shell Plugins - plugins to simulate command line interface shell
116
+ - NOS plugins - plugins to simulate Network Operating System commands
117
+
118
+ ## What not?
119
+
120
+ SIMNOS is a simulator, it does not emulate any of Network Control, Data
121
+ or Management planes, it merely takes the commands as input and responds
122
+ with predefined output.
123
+
124
+ ## Acknowledgments
125
+
126
+ SIMNOS is built upon the work of [FakeNOS](https://github.com/fakenos/fakenos). We are grateful to the original creators and contributors:
127
+
128
+ - [Denis Mulyalin](https://github.com/dmulyalin) - Original Creator of FakeNOS
129
+ - [Enric Perpinyà Pitarch](https://github.com/evilmonkey19) - Main Collaborator and Maintainer of FakeNOS
130
+
131
+ ### Inspired by and borrowed from
132
+
133
+ - [sshim](https://pythonhosted.org/sshim/) - library for testing and debugging SSH automation clients
134
+ - [PythonSSHServerTutorial](https://github.com/ramonmeza/PythonSSHServerTutorial) - tutorial on creating paramiko based SSH server
135
+ - [fake-switches](https://github.com/internap/fake-switches) - pluggable switch/router command-line simulator
136
+ - [ncs-netsim](https://developer.cisco.com/docs/nso/guides/#!the-network-simulator) - tool to simulate a network of devices
137
+ - [cisshgo](https://github.com/tbotnz/cisshgo) - concurrent SSH server to emulate network equipment for testing purposes
138
+ - [scrapli-replay](https://pypi.org/project/scrapli-replay/) - tools to enable easy testing of SSH programs and to create semi-interactive SSH servers
139
+
140
+ [github-discussions-link]: https://github.com/Route-Reflector/simnos/discussions
141
+ [github-discussions-badge]: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
142
+ [ruff-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
143
+ [ruff-link]: https://github.com/astral-sh/ruff
144
+ [pypi-pyversion-link]: https://pypi.python.org/pypi/simnos/
145
+ [pypi-pyversion-badge]: https://img.shields.io/pypi/pyversions/simnos.svg?logo=python
146
+ [pepy-downloads-link]: https://pepy.tech/project/simnos
147
+ [pepy-downloads-badge]: https://pepy.tech/badge/simnos
148
+ [github-tests-badge]: https://github.com/Route-Reflector/simnos/actions/workflows/main.yml/badge.svg
149
+ [github-tests-link]: https://github.com/Route-Reflector/simnos/actions
150
+ [pypi-latest-release-link]: https://pypi.python.org/pypi/simnos
151
+ [pypi-latest-release-badge]: https://img.shields.io/pypi/v/simnos.svg?logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NC41OSA2NC41OCI+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5jbHMtMSB7CiAgICAgICAgZmlsbDogIzQwMmE1OTsKICAgICAgfQoKICAgICAgLmNscy0xLCAuY2xzLTIgewogICAgICAgIHN0cm9rZS13aWR0aDogMHB4OwogICAgICB9CgogICAgICAuY2xzLTIgewogICAgICAgIGZpbGw6ICNmZmY7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8Zz4KICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJNOS42NywwaDQ1LjVjNS4xNS44LDguNTUsMy44NCw5LjQyLDkuMDR2NDYuNjJjLS42OCw0Ljc0LTQuNTQsOC4xNy05LjIzLDguNjctNy40Ni43OS0zNS0uNjYtNDUuMzIsMC00LjQxLjAxLTkuMTUtMy4xMy05Ljc5LTcuNzRDLS4wOCw1NC4xOS0uMDksMTAuMzQuMjUsNy45My44NSwzLjY3LDUuNTMuMjUsOS42NywwWiIvPgogICAgICA8Zz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0xMC4yMyw1Ljc4YzIuMTgtLjMxLDQxLjgzLS4zLDQ0LjAxLDAsMi4xNi4zLDMuOTUsMS43Myw0LjU3LDMuODItLjQyLDcuNjIuNTUsNDIuMDEsMCw0NS4zMi0uMzEsMS44Ni0yLjEsMy4xOC0zLjgyLDMuNjQtOC40OC0uNTctNDAuNDIuODctNDQuOTQuMTktMS45My0uMjktMy44OC0yLjA2LTQuMi00LjAxLS4zNi0yLjIxLS4zNi00Mi41NSwwLTQ0Ljc2LjM0LTIuMDksMi4yOC0zLjksNC4zOC00LjJaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDkuNTgsMTkuMDJjMTIuOTksMTYuNzEtMy4yMywzOS44My0yMy41LDM0LjMxLTEuMjMtLjMzLTcuMS0zLjAzLTYuOTktNC4wMWwzLjgyLTQuMmMxMi40MSw4LjgzLDI4LjQ3LTMuMzksMjQuNzEtMTcuMjUtMS40My01LjI3LTQuNS0yLjYyLDEuOTYtOC44NloiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik00MS40NywxOS41OGMtMTQuMzgtOS42Ni0zMS40OCw2LjczLTIyLjU2LDIxLjI2LS4wNSwxLjMtMi45NSwzLjM5LTMuODIsNC42NkMtLjM4LDI1LjIyLDI0Ljg3LjQyLDQ1LjM4LDE1LjAxYy4wNy4zMy0zLjM2LDQuMTgtMy45Miw0LjU3WiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTQxLjQ3LDE5LjU4Yy0xLjUzLDEuMDctMy0uNjMtNC45NC0xLjEyLTYuNDItMS42MS0xMy4zNi44OS0xNi44OCw2LjYyLTEsMS42Mi0xLjUyLDMuNDgtMi4yNCw1LjIyLS4wOC4yLS40Mi0uMzEtLjU2LDAtLjcsMS41NS4xOSw1LjkzLjc1LDcuNjUuMzcsMS4xNCwxLjM1LDEuNjgsMS4zMSwyLjg5LTguOTItMTQuNTMsOC4xOS0zMC45MSwyMi41Ni0yMS4yNloiLz4KICAgICAgICA8Zz4KICAgICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTM0LjQ3LDI0LjYyYzMuNTEtLjI0LDUuNzUsMyw0LjU3LDYuMjUtLjM3LDEuMDMtNi4wMSw3LjA4LTYuOTksNy43NC00LjM5LDIuOTMtOC4wMi0uNjQtNi44MS00Ljk0LjI3LS45Niw2LjU3LTguODYsOS4yMy05LjA0WiIvPgogICAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMzUuMjIsMjUuOTJjMS43Ni4wNywyLjkzLDIuMDEsMi43LDMuNjQtLjExLjgxLTguOTUsMTMuNTktMTEuNTYsNi41My0uNzUtMi40OSw2LjkzLTEwLjI0LDguODYtMTAuMTZaIi8+CiAgICAgICAgPC9nPgogICAgICA8L2c+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4=
simnos-2.0.0/README.md ADDED
@@ -0,0 +1,119 @@
1
+ [English](README.md) | [日本語](README.ja.md)
2
+
3
+ [![Downloads][pepy-downloads-badge]][pepy-downloads-link]
4
+ [![PyPI][pypi-latest-release-badge]][pypi-latest-release-link]
5
+ [![PyPI versions][pypi-pyversion-badge]][pypi-pyversion-link]
6
+ [![GitHub Discussion][github-discussions-badge]][github-discussions-link]
7
+ [![Ruff][ruff-badge]][ruff-link]
8
+ [![Tests][github-tests-badge]][github-tests-link]
9
+
10
+ # Simulated Network Operating Systems - SIMNOS
11
+
12
+ > "Reality is merely an illusion, albeit a very persistent one."
13
+ >
14
+ > ~ Albert Einstein
15
+
16
+ SIMNOS simulates Network Operating Systems interactions. You can simulate
17
+ network devices like Cisco IOS or Huawei SmartAX interactions over
18
+ SSH with little effort. This project is mainly intended for testing
19
+ and development purposes.
20
+
21
+ [Documentation](https://route-reflector.github.io/simnos/) | [Examples](https://route-reflector.github.io/simnos/examples/) | [Platforms](https://route-reflector.github.io/simnos/platforms/)
22
+
23
+ ## Origin
24
+
25
+ SIMNOS is an independent project derived from [FakeNOS](https://github.com/fakenos/fakenos), created by Denis Mulyalin and maintained by Enric Perpinyà Pitarch. After significant divergence in tooling, platforms, and architecture, it was rebranded as SIMNOS to avoid confusion with the upstream project.
26
+
27
+ **AI Transparency:** AI-assisted development (Claude Code, Codex, Gemini, etc.) is actively used in this project. All AI-generated changes are reviewed by a human maintainer before merging.
28
+
29
+ **Key differences from FakeNOS:**
30
+
31
+ - Package name: `simnos` (on PyPI)
32
+ - Package manager: uv (migrated from Poetry)
33
+ - Linter/Formatter: Ruff (migrated from Black/Pylint)
34
+ - Python support: 3.13 / 3.14
35
+ - CI: Modernized GitHub Actions workflow
36
+ - NOS platforms: 5 additional platforms enabled (brocade_fastiron, ciena_saos, fortinet, juniper_screenos, ruckus_fastiron)
37
+ - Paramiko: upgraded to 4.0 with DH Group Exchange server-mode workaround
38
+
39
+ ## Why?
40
+
41
+ Crucial aspect of writing applications or scripts for Network Automation is
42
+ testing, often testing done using physical or virtual instances of network
43
+ appliances running certain version of Network Operating System (NOS). That
44
+ approach, while gives best integration results, in many cases carries a lot
45
+ of overhead to setup, run and tear down as well as putting significant burden
46
+ on compute and storage resource utilization.
47
+
48
+ Other approach is to mock underlying libraries methods to fool applications
49
+ under testing into believing that it is getting output from real devices. That
50
+ approach works very well for unit testing, but fails to simulate such aspects
51
+ as connection establishment and handling.
52
+
53
+ SIMNOS positions itself somewhere in the middle between full integration testing
54
+ and testing that mocks device interactions. SIMNOS allows to create NOS plugins
55
+ to produce pre-defined output to test applications behavior while running servers
56
+ to establish connections with.
57
+
58
+ ## What?
59
+
60
+ SIMNOS can:
61
+
62
+ - Run thousands of servers to stress test applications
63
+ - Simulate Network Operating Systems Command Line Interface (CLI) interactions
64
+ - Provide high-level API to create custom NOS plugins
65
+ - Run in docker container to simplify integration with your infrastructure
66
+ - Make use of SIMNOS CLI tool for quick run and prototype simulations
67
+ - Works on Windows, Mac and Linux under Python 3.13 and 3.14
68
+
69
+ ## How?
70
+
71
+ Send input and get the output - this is how we interact with many
72
+ Network Operating Systems, SIMNOS allows to pre-define the output
73
+ to sent in response to certain input commands, making it ideal for
74
+ isolated feature testing.
75
+
76
+ SIMNOS is a micro-kernel framework that can be extended using plugins.
77
+ The core is kept small and optimized while most of the functionality
78
+ offloaded to plugins.
79
+
80
+ SIMNOS has these pluggable systems:
81
+
82
+ - Server Plugins - plugins responsible for running various servers to connect with
83
+ - Shell Plugins - plugins to simulate command line interface shell
84
+ - NOS plugins - plugins to simulate Network Operating System commands
85
+
86
+ ## What not?
87
+
88
+ SIMNOS is a simulator, it does not emulate any of Network Control, Data
89
+ or Management planes, it merely takes the commands as input and responds
90
+ with predefined output.
91
+
92
+ ## Acknowledgments
93
+
94
+ SIMNOS is built upon the work of [FakeNOS](https://github.com/fakenos/fakenos). We are grateful to the original creators and contributors:
95
+
96
+ - [Denis Mulyalin](https://github.com/dmulyalin) - Original Creator of FakeNOS
97
+ - [Enric Perpinyà Pitarch](https://github.com/evilmonkey19) - Main Collaborator and Maintainer of FakeNOS
98
+
99
+ ### Inspired by and borrowed from
100
+
101
+ - [sshim](https://pythonhosted.org/sshim/) - library for testing and debugging SSH automation clients
102
+ - [PythonSSHServerTutorial](https://github.com/ramonmeza/PythonSSHServerTutorial) - tutorial on creating paramiko based SSH server
103
+ - [fake-switches](https://github.com/internap/fake-switches) - pluggable switch/router command-line simulator
104
+ - [ncs-netsim](https://developer.cisco.com/docs/nso/guides/#!the-network-simulator) - tool to simulate a network of devices
105
+ - [cisshgo](https://github.com/tbotnz/cisshgo) - concurrent SSH server to emulate network equipment for testing purposes
106
+ - [scrapli-replay](https://pypi.org/project/scrapli-replay/) - tools to enable easy testing of SSH programs and to create semi-interactive SSH servers
107
+
108
+ [github-discussions-link]: https://github.com/Route-Reflector/simnos/discussions
109
+ [github-discussions-badge]: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
110
+ [ruff-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
111
+ [ruff-link]: https://github.com/astral-sh/ruff
112
+ [pypi-pyversion-link]: https://pypi.python.org/pypi/simnos/
113
+ [pypi-pyversion-badge]: https://img.shields.io/pypi/pyversions/simnos.svg?logo=python
114
+ [pepy-downloads-link]: https://pepy.tech/project/simnos
115
+ [pepy-downloads-badge]: https://pepy.tech/badge/simnos
116
+ [github-tests-badge]: https://github.com/Route-Reflector/simnos/actions/workflows/main.yml/badge.svg
117
+ [github-tests-link]: https://github.com/Route-Reflector/simnos/actions
118
+ [pypi-latest-release-link]: https://pypi.python.org/pypi/simnos
119
+ [pypi-latest-release-badge]: https://img.shields.io/pypi/v/simnos.svg?logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NC41OSA2NC41OCI+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5jbHMtMSB7CiAgICAgICAgZmlsbDogIzQwMmE1OTsKICAgICAgfQoKICAgICAgLmNscy0xLCAuY2xzLTIgewogICAgICAgIHN0cm9rZS13aWR0aDogMHB4OwogICAgICB9CgogICAgICAuY2xzLTIgewogICAgICAgIGZpbGw6ICNmZmY7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8Zz4KICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJNOS42NywwaDQ1LjVjNS4xNS44LDguNTUsMy44NCw5LjQyLDkuMDR2NDYuNjJjLS42OCw0Ljc0LTQuNTQsOC4xNy05LjIzLDguNjctNy40Ni43OS0zNS0uNjYtNDUuMzIsMC00LjQxLjAxLTkuMTUtMy4xMy05Ljc5LTcuNzRDLS4wOCw1NC4xOS0uMDksMTAuMzQuMjUsNy45My44NSwzLjY3LDUuNTMuMjUsOS42NywwWiIvPgogICAgICA8Zz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0xMC4yMyw1Ljc4YzIuMTgtLjMxLDQxLjgzLS4zLDQ0LjAxLDAsMi4xNi4zLDMuOTUsMS43Myw0LjU3LDMuODItLjQyLDcuNjIuNTUsNDIuMDEsMCw0NS4zMi0uMzEsMS44Ni0yLjEsMy4xOC0zLjgyLDMuNjQtOC40OC0uNTctNDAuNDIuODctNDQuOTQuMTktMS45My0uMjktMy44OC0yLjA2LTQuMi00LjAxLS4zNi0yLjIxLS4zNi00Mi41NSwwLTQ0Ljc2LjM0LTIuMDksMi4yOC0zLjksNC4zOC00LjJaIi8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDkuNTgsMTkuMDJjMTIuOTksMTYuNzEtMy4yMywzOS44My0yMy41LDM0LjMxLTEuMjMtLjMzLTcuMS0zLjAzLTYuOTktNC4wMWwzLjgyLTQuMmMxMi40MSw4LjgzLDI4LjQ3LTMuMzksMjQuNzEtMTcuMjUtMS40My01LjI3LTQuNS0yLjYyLDEuOTYtOC44NloiLz4KICAgICAgICA8cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik00MS40NywxOS41OGMtMTQuMzgtOS42Ni0zMS40OCw2LjczLTIyLjU2LDIxLjI2LS4wNSwxLjMtMi45NSwzLjM5LTMuODIsNC42NkMtLjM4LDI1LjIyLDI0Ljg3LjQyLDQ1LjM4LDE1LjAxYy4wNy4zMy0zLjM2LDQuMTgtMy45Miw0LjU3WiIvPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTQxLjQ3LDE5LjU4Yy0xLjUzLDEuMDctMy0uNjMtNC45NC0xLjEyLTYuNDItMS42MS0xMy4zNi44OS0xNi44OCw2LjYyLTEsMS42Mi0xLjUyLDMuNDgtMi4yNCw1LjIyLS4wOC4yLS40Mi0uMzEtLjU2LDAtLjcsMS41NS4xOSw1LjkzLjc1LDcuNjUuMzcsMS4xNCwxLjM1LDEuNjgsMS4zMSwyLjg5LTguOTItMTQuNTMsOC4xOS0zMC45MSwyMi41Ni0yMS4yNloiLz4KICAgICAgICA8Zz4KICAgICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTM0LjQ3LDI0LjYyYzMuNTEtLjI0LDUuNzUsMyw0LjU3LDYuMjUtLjM3LDEuMDMtNi4wMSw3LjA4LTYuOTksNy43NC00LjM5LDIuOTMtOC4wMi0uNjQtNi44MS00Ljk0LjI3LS45Niw2LjU3LTguODYsOS4yMy05LjA0WiIvPgogICAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMzUuMjIsMjUuOTJjMS43Ni4wNywyLjkzLDIuMDEsMi43LDMuNjQtLjExLjgxLTguOTUsMTMuNTktMTEuNTYsNi41My0uNzUtMi40OSw2LjkzLTEwLjI0LDguODYtMTAuMTZaIi8+CiAgICAgICAgPC9nPgogICAgICA8L2c+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4=
@@ -0,0 +1,152 @@
1
+ [project]
2
+ name = "simnos"
3
+ version = "2.0.0"
4
+ description = "Simulated Network Operating System"
5
+ authors = [
6
+ { name = "KeroRoute lab" },
7
+ ]
8
+ maintainers = [
9
+ { name = "KeroRoute lab" },
10
+ ]
11
+ license = { text = "MIT" }
12
+ readme = "README.md"
13
+ keywords = [
14
+ "NetworkAutomation",
15
+ "Testing",
16
+ "SSH",
17
+ "Integration",
18
+ "NOS"
19
+ ]
20
+ classifiers = [
21
+ "Intended Audience :: Telecommunications Industry",
22
+ "Intended Audience :: Developers",
23
+ "Intended Audience :: Education",
24
+ "Intended Audience :: Information Technology",
25
+ "Intended Audience :: System Administrators",
26
+ "Operating System :: Microsoft :: Windows",
27
+ "Operating System :: POSIX :: Linux",
28
+ "Operating System :: Unix",
29
+ "Operating System :: MacOS",
30
+ "Topic :: Utilities",
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.13",
33
+ "Programming Language :: Python :: 3.14",
34
+ "License :: OSI Approved :: MIT License",
35
+ ]
36
+ requires-python = ">=3.13,<3.15"
37
+ dependencies = [
38
+ "paramiko>=4.0,<5.0",
39
+ "pyyaml<7.0",
40
+ "pydantic<3.0",
41
+ "jinja2>=3.1.6",
42
+ "detect==2020.12.*",
43
+ ]
44
+
45
+
46
+ [project.urls]
47
+ Homepage = "https://github.com/Route-Reflector/simnos/"
48
+ Documentation = "https://route-reflector.github.io/simnos/"
49
+
50
+ [project.scripts]
51
+ simnos = "simnos.plugins.utils.cli:run_cli"
52
+
53
+ [tool.ruff]
54
+ line-length = 120
55
+ target-version = "py313"
56
+ exclude = ["venv", ".venv", "env", ".env"]
57
+
58
+ [tool.ruff.lint]
59
+ select = [
60
+ "B", # flake8-bugbear
61
+ "C4", # flake8-comprehensions
62
+ "E", # pycodestyle
63
+ "F", # pyflakes
64
+ "I", # isort
65
+ "PERF", # Perflint
66
+ "RUF", # ruff itself
67
+ "S", # flake8-bandit
68
+ "SIM", # flake8-simplify
69
+ "UP", # pyupgrade
70
+ "W", # pycodestyle
71
+ ]
72
+ ignore = [
73
+ "RUF001", # ambiguous-unicode-character-string
74
+ "RUF002", # ambiguous-unicode-character-docstring
75
+ "RUF003", # ambiguous-unicode-character-comment
76
+ "RUF012", # mutable-class-default
77
+ "SIM108", # if-else-block-instead-of-if-exp
78
+ ]
79
+ dummy-variable-rgx = "^_.*"
80
+
81
+ [tool.ruff.lint.per-file-ignores]
82
+ "tests/*" = [
83
+ "S101", # Allow use of assert in tests
84
+ "S311", # Allow use of random in tests
85
+ "S105", # Allow use of hardcoded password to "password"
86
+ "S106", # Allow use of hardcoded password in tests
87
+ "S104", # Allow binding to all interfaces in tests
88
+ "S603", # Allow subprocess calls in tests (e.g. docker compose)
89
+ "S607", # Allow starting a process with a partial executable path in tests
90
+ ]
91
+ "update_platforms.py" = [
92
+ "S108", # Probably insecure usage of temp file/directory - this is a script
93
+ "S603", # Use of subprocess without shell=True - this is a script
94
+ "S607", # Starting a process with a partial executable path - this is a script
95
+ ]
96
+
97
+ [tool.ruff.lint.isort]
98
+ force-sort-within-sections = true
99
+
100
+ [tool.bandit]
101
+ exclude_dirs = ["./tests/", "./.venv", "./docs/", "./update_platforms.py"]
102
+ tests = ["B201", "B301"]
103
+ skips = ["B101", "B601"]
104
+
105
+
106
+ [tool.coverage.run]
107
+ branch = true
108
+ omit = [".*", ".venv"]
109
+ command_line = "-m pytest"
110
+
111
+ [tool.coverage.report]
112
+ fail_under = 80
113
+ show_missing = true
114
+
115
+ [tool.coverage.html]
116
+ directory = "coverage_html_report"
117
+
118
+ [tool.pytest.ini_options]
119
+ testpaths = ["tests"]
120
+ addopts = "-vv"
121
+
122
+ [tool.uv.build-backend]
123
+ module-name = "simnos"
124
+ module-root = ""
125
+
126
+ [build-system]
127
+ requires = ["uv_build>=0.9.6,<0.10.0"]
128
+ build-backend = "uv_build"
129
+
130
+ [dependency-groups]
131
+ dev = [
132
+ "ruff>=0.14.4", # Linter
133
+ "ruamel-yaml", # YAML parser
134
+ "ty>=0.0.1a26", # Type checkers
135
+ "pytest", # Testing framework
136
+ "pytest-repeat", # Pytest: Repeat tests
137
+ "pytest-timeout", # Pytest: Timeout tests
138
+ "pytest-xdist>=3.8.0", # Pytest: Parallel test execution
139
+ "bandit",
140
+ "coverage",
141
+ "invoke",
142
+ "pre-commit>=3.8.0,<4.0.0",
143
+ "pyenchant",
144
+ "netmiko",
145
+ "requests",
146
+ "psutil",
147
+ "mkdocstrings[crystal,python]",
148
+ "mkdocs-material",
149
+ "mkdocs-static-i18n",
150
+ "pymdown-extensions",
151
+ "yamllint", # YAML linter
152
+ ]
@@ -0,0 +1,11 @@
1
+ """
2
+ This module provides the main classes of the SimNOS library.
3
+ It provides the SimNOS class for creating a fake network
4
+ operating system and the Nos class for creating a network
5
+ operating system object.
6
+ """
7
+
8
+ from simnos.core.nos import Nos
9
+ from simnos.core.simnos import SimNOS, simnos
10
+
11
+ __all__ = ("Nos", "SimNOS", "simnos")
File without changes
@@ -0,0 +1,97 @@
1
+ """
2
+ This module sets up the host object which is the main object in SIMNOS.
3
+ It provides the methods to start and stop the server instance for the host.
4
+ It also validates the host object using pydantic.
5
+ """
6
+
7
+ import logging
8
+
9
+ from simnos.core.nos import Nos, available_platforms
10
+ from simnos.core.pydantic_models import ModelHost
11
+
12
+ log = logging.getLogger(__name__)
13
+
14
+
15
+ class Host:
16
+ """
17
+ Host class to build host instances to use with SIMNOS.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ name: str,
23
+ username: str,
24
+ password: str,
25
+ port: int,
26
+ server: dict,
27
+ shell: dict,
28
+ nos: dict,
29
+ simnos,
30
+ platform: str | None = None,
31
+ configuration_file: str | None = None,
32
+ ) -> None:
33
+ self.name: str = name
34
+ self.server_inventory: dict = server
35
+ self.shell_inventory: dict = shell
36
+ self.nos_inventory: dict = nos
37
+ self.username: str = username
38
+ self.password: str = password
39
+ self.port: int = port
40
+ self.simnos = simnos # SimNOS object
41
+ self.shell_inventory["configuration"].setdefault("base_prompt", self.name)
42
+ self.running = False
43
+ self.server = None
44
+ self.server_plugin = None
45
+ self.shell_plugin = None
46
+ self.nos_plugin = None
47
+ self.nos = None
48
+ self.platform: str | None = platform
49
+ self.configuration_file: str | None = configuration_file
50
+
51
+ if self.platform:
52
+ self.nos_inventory["plugin"] = self.platform
53
+
54
+ self._validate()
55
+
56
+ def start(self):
57
+ """Method to start server instance for this host."""
58
+ self.server_plugin = self.simnos.servers_plugins[self.server_inventory["plugin"]]
59
+ self.shell_plugin = self.simnos.shell_plugins[self.shell_inventory["plugin"]]
60
+ if self.platform:
61
+ self.nos_inventory["plugin"] = self.platform
62
+ self.nos_plugin = self.simnos.nos_plugins.get(self.nos_inventory["plugin"], self.nos_inventory["plugin"])
63
+ self.nos = (
64
+ Nos(filename=self.nos_plugin, configuration_file=self.configuration_file)
65
+ if not isinstance(self.nos_plugin, Nos)
66
+ else self.nos_plugin
67
+ )
68
+ self.server = self.server_plugin(
69
+ shell=self.shell_plugin,
70
+ shell_configuration=self.shell_inventory["configuration"],
71
+ nos=self.nos,
72
+ nos_inventory_config=self.nos_inventory.get("configuration", {}),
73
+ port=self.port,
74
+ username=self.username,
75
+ password=self.password,
76
+ **self.server_inventory["configuration"],
77
+ )
78
+ self.server.start()
79
+ self.running = True
80
+
81
+ def stop(self):
82
+ """Method to stop server instance for this host."""
83
+ self.server.stop()
84
+ self.server = None
85
+ self.running = False
86
+
87
+ def _validate(self):
88
+ """Validate that the host has the required attributes using pydantic"""
89
+ if self.platform:
90
+ self._check_if_platform_is_supported(self.platform)
91
+ ModelHost(**self.__dict__)
92
+
93
+ def _check_if_platform_is_supported(self, platform: str):
94
+ """Check if the platform is supported"""
95
+ if platform not in available_platforms:
96
+ msg = f"Platform {platform} is not supported by SIMNOS. Supported platforms are: {available_platforms}"
97
+ raise ValueError(msg)