Mock SSH Server
-----------------
Installation
-----------
## Python
```
pip install ssh-mock
```
## Docker
See docker-compose.yml or run:
```
```
## YML Configuration
```yaml
version: "3.7"
commands:
# Simple command
- command: echo hello
stdout: "Hello World!"
returncode: 0
# Command matching regex
- command: interface.*
stdout: ""
# Return values from command via JINJA template
- command: exec echo.*
stdout_template: "{{command[9:]|trim|trim('''')|trim('\"')}}"
returncode: 0
# Modify the Hostname
- command: enable
stdout: "Password"
modify_host: HOST#
returncode: 0
# Use multiple lines
- command: show users
stdout: " Line User Host(s) Idle Location\n* 1 vty 0 rootuser idle 00:00:00\n example.test.de\n\n Interface User Mode Idle Peer Address\n\n"
returncode: 0
- command: show interfaces description
stdout: |
Interface Status Protocol Description
Vl1 up up
Vl308 up up
Gi1/0/1 up up Access Port
Gi1/0/12 down down Access Port
Gi1/1/1 down down
Gi1/1/2 down down
Te1/1/3 down down
Te1/1/4 up up
```
# Outdated documentation:
## Blocking Server
A blocking server is often used for development purposes.
Simply write yourself a `server.py` file:
```python
from typing import Optional
from ssh_mock import Server
def handler(command: str) -> Optional[str]:
if command.startswith("ls"):
return "file1\nfile2\n"
elif command.startswith("echo"):
return command[4:].strip() + "\n"
if __name__ == "__main__":
Server(command_handler=handler, port=5050).run_blocking()
```
And run it:
```
$ python3 server.py
```
In a separate terminal, run:
```
$ ssh root@127.0.0.1 -p 5050 echo 42
42
$ ssh root@127.0.0.1 -p 5050 ls
file1
file2
```
(if you are prompted for a password, you can leave it blank)
Note how you need to specify a non standard port (5050). Using the standard port (22) would require root permissions
and is probably unsafe.
## Non-Blocking Server
A non blocking server is often used in tests.
This server runs in a thread and allows you to run some tests in parallel.
```python
import paramiko
import pytest
from mock_ssh import Server
def handler(command):
if command == "ls":
return "file1\nfile2\n"
@pytest.fixture
def server():
with Server(command_handler=handler) as server:
yield server
def my_ls(host, port):
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect(hostname=host,
port=port,
username="root",
password="",
allow_agent=False,
look_for_keys=False)
return c.exec_command("ls")[1].read().decode().splitlines()
def test_ls(server):
assert my_ls(server.host, server.port) == ["file1", "file2"]
```
## Thanks
This was initally a fork of [https://github.com/d1618033/fake-ssh](https://github.com/d1618033/fake-ssh). Thanks [David](https://github.com/d1618033) for your work!
Raw data
{
"_id": null,
"home_page": "https://github.com/DanielHabenicht/mock-ssh.git",
"name": "ssh-mock",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8.1,<4.0.0",
"maintainer_email": "",
"keywords": "SSH,Server,Mocking,Mock,Testing",
"author": "DanielHabenicht",
"author_email": "daniel-habenicht@outlook.de",
"download_url": "https://files.pythonhosted.org/packages/3c/9b/ae599a2c5353d37d18cc0a743a0ccb9550cf46ad7cbb919d538298fff6ce/ssh_mock-0.2.2.tar.gz",
"platform": null,
"description": "Mock SSH Server\n-----------------\n\nInstallation\n-----------\n\n## Python\n\n```\npip install ssh-mock\n```\n\n## Docker\n\nSee docker-compose.yml or run:\n\n```\n\n```\n\n## YML Configuration\n\n```yaml\t\nversion: \"3.7\"\ncommands:\n# Simple command\n - command: echo hello\n stdout: \"Hello World!\"\n returncode: 0\n# Command matching regex\n - command: interface.*\n stdout: \"\"\n# Return values from command via JINJA template\n - command: exec echo.*\n stdout_template: \"{{command[9:]|trim|trim('''')|trim('\\\"')}}\"\n returncode: 0\n# Modify the Hostname\n - command: enable\n stdout: \"Password\"\n modify_host: HOST#\n returncode: 0\n# Use multiple lines\n - command: show users\n stdout: \" Line User Host(s) Idle Location\\n* 1 vty 0 rootuser idle 00:00:00\\n example.test.de\\n\\n Interface User Mode Idle Peer Address\\n\\n\"\n returncode: 0\n - command: show interfaces description\n stdout: | \n Interface Status Protocol Description\n Vl1 up up\n Vl308 up up\n Gi1/0/1 up up Access Port\n Gi1/0/12 down down Access Port\n Gi1/1/1 down down\n Gi1/1/2 down down\n Te1/1/3 down down\n Te1/1/4 up up\n```\n\n# Outdated documentation:\n\n## Blocking Server\n\nA blocking server is often used for development purposes.\n\nSimply write yourself a `server.py` file:\n\n```python\nfrom typing import Optional\nfrom ssh_mock import Server\n\n\ndef handler(command: str) -> Optional[str]:\n if command.startswith(\"ls\"):\n return \"file1\\nfile2\\n\"\n elif command.startswith(\"echo\"):\n return command[4:].strip() + \"\\n\"\n\nif __name__ == \"__main__\":\n Server(command_handler=handler, port=5050).run_blocking()\n\n```\n\nAnd run it:\n\n```\n$ python3 server.py\n```\n\nIn a separate terminal, run:\n\n```\n$ ssh root@127.0.0.1 -p 5050 echo 42\n42\n \n$ ssh root@127.0.0.1 -p 5050 ls\nfile1\nfile2\n```\n\n(if you are prompted for a password, you can leave it blank)\n\nNote how you need to specify a non standard port (5050). Using the standard port (22) would require root permissions\nand is probably unsafe.\n\n\n## Non-Blocking Server\n\nA non blocking server is often used in tests. \n\nThis server runs in a thread and allows you to run some tests in parallel.\n\n```python\nimport paramiko\nimport pytest\n\nfrom mock_ssh import Server\n\n\ndef handler(command):\n if command == \"ls\":\n return \"file1\\nfile2\\n\"\n\n\n@pytest.fixture\ndef server():\n with Server(command_handler=handler) as server:\n yield server\n\n\ndef my_ls(host, port):\n c = paramiko.SSHClient()\n c.set_missing_host_key_policy(paramiko.AutoAddPolicy())\n c.connect(hostname=host,\n port=port,\n username=\"root\",\n password=\"\",\n allow_agent=False,\n look_for_keys=False)\n return c.exec_command(\"ls\")[1].read().decode().splitlines()\n\n\ndef test_ls(server):\n assert my_ls(server.host, server.port) == [\"file1\", \"file2\"]\n\n```\n\n\n## Thanks\n\nThis was initally a fork of [https://github.com/d1618033/fake-ssh](https://github.com/d1618033/fake-ssh). Thanks [David](https://github.com/d1618033) for your work!",
"bugtrack_url": null,
"license": "MIT",
"summary": "Mocks an SSH Server",
"version": "0.2.2",
"project_urls": {
"Homepage": "https://github.com/DanielHabenicht/mock-ssh.git",
"Repository": "https://github.com/DanielHabenicht/mock-ssh.git"
},
"split_keywords": [
"ssh",
"server",
"mocking",
"mock",
"testing"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bb97ed21cc74a6a490fb43a8cb0e465380942a436ca0819374dbfc0842c76cb0",
"md5": "cf9312cbe5eca98440a196f974cfa08a",
"sha256": "a0d9e516b30b799c7f9f6693cda81b36cb4f5f5bd7e228554daa4defa097e2c9"
},
"downloads": -1,
"filename": "ssh_mock-0.2.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cf9312cbe5eca98440a196f974cfa08a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8.1,<4.0.0",
"size": 9298,
"upload_time": "2023-11-16T11:17:20",
"upload_time_iso_8601": "2023-11-16T11:17:20.659475Z",
"url": "https://files.pythonhosted.org/packages/bb/97/ed21cc74a6a490fb43a8cb0e465380942a436ca0819374dbfc0842c76cb0/ssh_mock-0.2.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3c9bae599a2c5353d37d18cc0a743a0ccb9550cf46ad7cbb919d538298fff6ce",
"md5": "ac10df68ae9d10ba6a4cc26064adf12e",
"sha256": "1ad04b7c9ed3dda0d9ccb4ab9d8a564dc35828999eef4016fc9bb6a960f4deb1"
},
"downloads": -1,
"filename": "ssh_mock-0.2.2.tar.gz",
"has_sig": false,
"md5_digest": "ac10df68ae9d10ba6a4cc26064adf12e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8.1,<4.0.0",
"size": 9637,
"upload_time": "2023-11-16T11:17:23",
"upload_time_iso_8601": "2023-11-16T11:17:23.786300Z",
"url": "https://files.pythonhosted.org/packages/3c/9b/ae599a2c5353d37d18cc0a743a0ccb9550cf46ad7cbb919d538298fff6ce/ssh_mock-0.2.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-16 11:17:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "DanielHabenicht",
"github_project": "mock-ssh",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "ssh-mock"
}