-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support profile (just like .ssh/config) configuration
- Loading branch information
Kenson Man
committed
Oct 20, 2022
1 parent
4aec063
commit 0b2b2b8
Showing
12 changed files
with
548 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,11 @@ | ||
paramiko==2.10.4 | ||
tornado==5.1.1; python_version < '3.5' | ||
tornado==6.1.0; python_version >= '3.5' | ||
PyYAML>=5.4.1 | ||
|
||
#The following package used for testing | ||
#pytest | ||
#pytest-cov | ||
#codecov | ||
#flake8 | ||
#mock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
required: true #If true, user have to select one of the profiles | ||
profiles: | ||
- name: sample1 | ||
description: "Long description" | ||
host: localhost | ||
port: 22 | ||
#optional, if specified, the username field should not be shown on the template | ||
username: robey | ||
|
||
- name: sample2 | ||
description: "Long description" | ||
host: localhost | ||
port: 22 | ||
#optional, if specified, the username field should not be shown on the template | ||
username: robey | ||
#optional, if specified. | ||
#The below private key is clone from ./tests/data/user_rsa_key | ||
private-key: | | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIICXQIBAAKBgQDI7iK3d8eWYZlYloat94c5VjtFY7c/0zuGl8C7uMnZ3t6i2G99 | ||
66hEW0nCFSZkOW5F0XKEVj+EUCHvo8koYC6wiohAqWQnEwIoOoh7GSAcB8gP/qaq | ||
+adIl/Rvlby/mHakj+y05LBND6nFWHAn1y1gOFFKUXSJNRZPXSFy47gqzwIBIwKB | ||
gQCbANjz7q/pCXZLp1Hz6tYHqOvlEmjK1iabB1oqafrMpJ0eibUX/u+FMHq6StR5 | ||
M5413BaDWHokPdEJUnabfWXXR3SMlBUKrck0eAer1O8m78yxu3OEdpRk+znVo4DL | ||
guMeCdJB/qcF0kEsx+Q8HP42MZU1oCmk3PbfXNFwaHbWuwJBAOQ/ry/hLD7AqB8x | ||
DmCM82A9E59ICNNlHOhxpJoh6nrNTPCsBAEu/SmqrL8mS6gmbRKUaya5Lx1pkxj2 | ||
s/kWOokCQQDhXCcYXjjWiIfxhl6Rlgkk1vmI0l6785XSJNv4P7pXjGmShXfIzroh | ||
S8uWK3tL0GELY7+UAKDTUEVjjQdGxYSXAkEA3bo1JzKCwJ3lJZ1ebGuqmADRO6UP | ||
40xH977aadfN1mEI6cusHmgpISl0nG5YH7BMsvaT+bs1FUH8m+hXDzoqOwJBAK3Z | ||
X/za+KV/REya2z0b+GzgWhkXUGUa/owrEBdHGriQ47osclkUgPUdNqcLmaDilAF4 | ||
1Z4PHPrI5RJIONAx+JECQQC/fChqjBgFpk6iJ+BOdSexQpgfxH/u/457W10Y43HR | ||
soS+8btbHqjQkowQ/2NTlUfWvqIlfxs6ZbFsIp/HrhZL | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import pytest, os, re, yaml, random | ||
from tornado.options import options | ||
from tornado.testing import AsyncTestCase, AsyncHTTPTestCase | ||
from webssh.main import make_app, make_handlers | ||
from webssh.settings import get_app_settings | ||
from tests.utils import make_tests_data_path | ||
from yaml.loader import SafeLoader | ||
|
||
class TestYAMLLoading(object): | ||
def test_profile_samples(self): | ||
if 'PROFILES' in os.environ: del os.environ['PROFILES'] | ||
assert 'profiles' not in get_app_settings(options) | ||
|
||
os.environ['PROFILES']=make_tests_data_path('profiles-sample.yaml') | ||
assert 'profiles' in get_app_settings(options) | ||
profiles=get_app_settings(options)['profiles']['profiles'] | ||
assert profiles[0]['name']=='sample1' | ||
assert profiles[0]['description']=='Long description' | ||
assert profiles[0]['host']=='localhost' | ||
assert profiles[0]['port']==22 | ||
assert profiles[0]['username']=='robey' | ||
|
||
assert profiles[1]['name']=='sample2' | ||
assert profiles[1]['description']=='Long description' | ||
assert profiles[1]['host']=='localhost' | ||
assert profiles[1]['port']==22 | ||
assert profiles[1]['username']=='robey' | ||
assert profiles[1]['private-key']==open(make_tests_data_path('user_rsa_key'), 'r').read() | ||
del os.environ['PROFILES'] | ||
|
||
class _TestBasic_(object): | ||
running = [True] | ||
sshserver_port = 2200 | ||
body = 'hostname={host}&port={port}&profile={profile}&username={username}&password={password}' | ||
headers = {'Cookie': '_xsrf=yummy'} | ||
|
||
def _getApp_(self, **kwargs): | ||
loop = self.io_loop | ||
options.debug = False | ||
options.policy = random.choice(['warning', 'autoadd']) | ||
options.hostfile = '' | ||
options.syshostfile = '' | ||
options.tdstream = '' | ||
options.delay = 0.1 | ||
#options.profiles=make_tests_data_path('tests/data/profiles-sample.yaml') | ||
app = make_app(make_handlers(loop, options), get_app_settings(options)) | ||
return app | ||
|
||
class TestWebGUIWithProfiles(AsyncHTTPTestCase, _TestBasic_): | ||
def get_app(self): | ||
try: | ||
os.environ['PROFILES']=make_tests_data_path('profiles-sample.yaml') | ||
return self._getApp_() | ||
finally: | ||
del os.environ['PROFILES'] | ||
|
||
|
||
def test_get_app_settings(self): | ||
try: | ||
os.environ['PROFILES']=make_tests_data_path('profiles-sample.yaml') | ||
settings=get_app_settings(options) | ||
assert 'profiles' in settings | ||
profiles=settings['profiles']['profiles'] | ||
assert profiles[0]['name']=='sample1' | ||
assert profiles[0]['description']=='Long description' | ||
assert profiles[0]['host']=='localhost' | ||
assert profiles[0]['port']==22 | ||
assert profiles[0]['username']=='robey' | ||
|
||
assert profiles[1]['name']=='sample2' | ||
assert profiles[1]['description']=='Long description' | ||
assert profiles[1]['host']=='localhost' | ||
assert profiles[1]['port']==22 | ||
assert profiles[1]['username']=='robey' | ||
assert profiles[1]['private-key']==open(make_tests_data_path('user_rsa_key'), 'r').read() | ||
finally: | ||
del os.environ['PROFILES'] | ||
|
||
def test_without_profiles(self): | ||
rep = self.fetch('/') | ||
assert rep.code==200, 'Testing server response status code: {0}'.format(rep.code) | ||
assert str(rep.body).index('<!-- PROFILES -->')>=0, 'Expected the "profiles.html" but "index.html"' | ||
|
||
class TestWebGUIWithoutProfiles(AsyncHTTPTestCase, _TestBasic_): | ||
def get_app(self): | ||
if 'PROFILES' in os.environ: del os.environ['PROFILES'] | ||
return self._getApp_() | ||
|
||
def test_get_app_settings(self): | ||
if 'PROFILES' in os.environ: del os.environ['PROFILES'] | ||
settings=get_app_settings(options) | ||
assert 'profiles' not in settings | ||
|
||
def test_with_profiles(self): | ||
rep = self.fetch('/') | ||
assert rep.code==200, 'Testing server response status code: {0}'.format(rep.code) | ||
with pytest.raises(ValueError): | ||
str(rep.body).index('<!-- PROFILES -->') | ||
assert False, 'Expected the origin "index.html" but "profiles.html"' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.