Commit 8452d75d authored by ibuler's avatar ibuler

Finished SDK

parent cb232113
...@@ -9,6 +9,7 @@ import time ...@@ -9,6 +9,7 @@ import time
from .session import Session from .session import Session
from .models import Server from .models import Server
from .utils import wrap_with_line_feed as wr
logger = logging.getLogger(__file__) logger = logging.getLogger(__file__)
...@@ -24,7 +25,7 @@ class ProxyServer: ...@@ -24,7 +25,7 @@ class ProxyServer:
self.connecting = True self.connecting = True
def proxy(self, asset, system_user): def proxy(self, asset, system_user):
self.send_connecting_message() self.send_connecting_message(asset, system_user)
self.server = self.get_server_conn(asset, system_user) self.server = self.get_server_conn(asset, system_user)
if self.server is None: if self.server is None:
return return
...@@ -41,23 +42,28 @@ class ProxyServer: ...@@ -41,23 +42,28 @@ class ProxyServer:
system user system user
:return: True or False :return: True or False
""" """
return True return self.app.service.validate_user_asset_permission(
self.client.user.id, asset.id, system_user.id
)
def get_system_user_auth(self, system_user): def get_system_user_auth(self, system_user):
""" """
Get the system user auth ..., using this to connect asset Get the system user auth ..., using this to connect asset
:return: system user have full info :return: system user have full info
""" """
system_user.password, system_user.private_key = \
self.app.service.get_system_user_auth_info(system_user)
def get_server_conn(self, asset, system_user): def get_server_conn(self, asset, system_user):
logger.info("Connect to %s" % asset.hostname) logger.info("Connect to %s" % asset.hostname)
if not self.validate_permission(asset, system_user): if not self.validate_permission(asset, system_user):
self.client.send(b'No permission') self.client.send(_('No permission'))
return None return None
self.get_system_user_auth(system_user) self.get_system_user_auth(system_user)
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print(asset.ip, asset.port, system_user.username, system_user.password, system_user.private_key)
try: try:
ssh.connect(asset.ip, port=asset.port, ssh.connect(asset.ip, port=asset.port,
username=system_user.username, username=system_user.username,
...@@ -65,10 +71,10 @@ class ProxyServer: ...@@ -65,10 +71,10 @@ class ProxyServer:
pkey=system_user.private_key, pkey=system_user.private_key,
timeout=TIMEOUT) timeout=TIMEOUT)
except paramiko.AuthenticationException as e: except paramiko.AuthenticationException as e:
self.client.send("[Errno 66] Authentication failed: {}".format(e).encode("utf-8")) self.client.send(wr("[Errno 66] {}".format(e)))
return None return None
except socket.error as e: except socket.error as e:
self.client.send(" {}".format(e).encode("utf-8")) self.client.send(wr(" {}".format(e)))
return None return None
finally: finally:
self.connecting = False self.connecting = False
...@@ -93,10 +99,10 @@ class ProxyServer: ...@@ -93,10 +99,10 @@ class ProxyServer:
thread.daemon = True thread.daemon = True
thread.start() thread.start()
def send_connecting_message(self): def send_connecting_message(self, asset, system_user):
def func(): def func():
delay = 0.0 delay = 0.0
self.client.send('Connecting to {} {:.1f}'.format(self.server, delay).encode('utf-8')) self.client.send('Connecting to {}@{} {:.1f}'.format(system_user, asset, delay))
while self.connecting and delay < TIMEOUT: while self.connecting and delay < TIMEOUT:
self.client.send('\x08\x08\x08{:.1f}'.format(delay).encode('utf-8')) self.client.send('\x08\x08\x08{:.1f}'.format(delay).encode('utf-8'))
time.sleep(0.1) time.sleep(0.1)
......
...@@ -9,7 +9,8 @@ from jms.models import Asset, SystemUser, AssetGroup ...@@ -9,7 +9,8 @@ from jms.models import Asset, SystemUser, AssetGroup
from . import char from . import char
from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \ from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \
wrap_with_primary as primary, wrap_with_warning as warning, \ wrap_with_primary as primary, wrap_with_warning as warning, \
is_obj_attr_has, is_obj_attr_eq, sort_assets, TtyIOParser is_obj_attr_has, is_obj_attr_eq, sort_assets, TtyIOParser, \
ugettext as _
from .forward import ProxyServer from .forward import ProxyServer
from .session import Session from .session import Session
...@@ -31,7 +32,7 @@ class InteractiveServer: ...@@ -31,7 +32,7 @@ class InteractiveServer:
def display_banner(self): def display_banner(self):
self.client.send(char.CLEAR_CHAR) self.client.send(char.CLEAR_CHAR)
banner = """\n {title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}\r\n\r banner = _("""\n {title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}\r\n\r
1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r 1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r
2) 输入 {green}/{end} + {green}IP, 主机名 or 备注 {end}搜索. 如: /ip\r 2) 输入 {green}/{end} + {green}IP, 主机名 or 备注 {end}搜索. 如: /ip\r
3) 输入 {green}P/p{end} 显示您有权限的主机.\r 3) 输入 {green}P/p{end} 显示您有权限的主机.\r
...@@ -41,13 +42,13 @@ class InteractiveServer: ...@@ -41,13 +42,13 @@ class InteractiveServer:
7) 输入 {green}U/u{end} 批量上传文件.(未完成)\r 7) 输入 {green}U/u{end} 批量上传文件.(未完成)\r
8) 输入 {green}D/d{end} 批量下载文件.(未完成)\r 8) 输入 {green}D/d{end} 批量下载文件.(未完成)\r
9) 输入 {green}H/h{end} 帮助.\r 9) 输入 {green}H/h{end} 帮助.\r
0) 输入 {green}Q/q{end} 退出.\r\n""".format( 0) 输入 {green}Q/q{end} 退出.\r\n""").format(
title="\033[1;32m", green="\033[32m", title="\033[1;32m", green="\033[32m",
end="\033[0m", user=self.client.user end="\033[0m", user=self.client.user
) )
self.client.send(banner) self.client.send(banner)
def get_choice(self, prompt=b'Opt> '): def get_choice(self, prompt='Opt> '):
"""实现了一个ssh input, 提示用户输入, 获取并返回 """实现了一个ssh input, 提示用户输入, 获取并返回
:return user input string :return user input string
...@@ -150,10 +151,10 @@ class InteractiveServer: ...@@ -150,10 +151,10 @@ class InteractiveServer:
self.get_user_asset_groups() self.get_user_asset_groups()
if len(self.asset_groups) == 0: if len(self.asset_groups) == 0:
self.client.send(warning("Nothing")) self.client.send(warning(_("Nothing")))
return return
fake_group = AssetGroup(name="Name", assets_amount="Assets", comment="Comment") fake_group = AssetGroup(name=_("Name"), assets_amount=_("Assets"), comment=_("Comment"))
id_max_length = max(len(str(len(self.asset_groups))), 5) id_max_length = max(len(str(len(self.asset_groups))), 5)
name_max_length = max(max([len(group.name) for group in self.asset_groups]), 15) name_max_length = max(max([len(group.name) for group in self.asset_groups]), 15)
amount_max_length = max(len(str(max([group.assets_amount for group in self.asset_groups]))), 10) amount_max_length = max(len(str(max([group.assets_amount for group in self.asset_groups]))), 10)
...@@ -164,7 +165,7 @@ class InteractiveServer: ...@@ -164,7 +165,7 @@ class InteractiveServer:
self.client.send(title(header.format(fake_group, "ID"))) self.client.send(title(header.format(fake_group, "ID")))
for index, group in enumerate(self.asset_groups): for index, group in enumerate(self.asset_groups):
self.client.send(wr(line.format(group, index))) self.client.send(wr(line.format(group, index)))
self.client.send(wr("Total: {}".format(len(self.asset_groups)), before=1)) self.client.send(wr(_("Total: {}").format(len(self.asset_groups)), before=1))
def display_group_assets(self, _id): def display_group_assets(self, _id):
self.search_result = self.asset_groups[_id].assets_granted self.search_result = self.asset_groups[_id].assets_granted
...@@ -176,7 +177,7 @@ class InteractiveServer: ...@@ -176,7 +177,7 @@ class InteractiveServer:
return return
self.search_result = sort_assets(self.search_result, self.app.config["ASSET_LIST_SORT_BY"]) self.search_result = sort_assets(self.search_result, self.app.config["ASSET_LIST_SORT_BY"])
fake_asset = Asset(hostname="Hostname", ip="IP", system_users_join="LoginAs", comment="Comment") fake_asset = Asset(hostname=_("Hostname"), ip=_("IP"), system_users_join=_("LoginAs"), comment=_("Comment"))
id_max_length = max(len(str(len(self.search_result))), 3) id_max_length = max(len(str(len(self.search_result))), 3)
hostname_max_length = max(max([len(asset.hostname) for asset in self.search_result + [fake_asset]]), 15) hostname_max_length = max(max([len(asset.hostname) for asset in self.search_result + [fake_asset]]), 15)
sysuser_max_length = max([len(asset.system_users_join) for asset in self.search_result + [fake_asset]]) sysuser_max_length = max([len(asset.system_users_join) for asset in self.search_result + [fake_asset]])
...@@ -188,7 +189,7 @@ class InteractiveServer: ...@@ -188,7 +189,7 @@ class InteractiveServer:
self.client.send(wr(title(header.format(fake_asset, "ID")))) self.client.send(wr(title(header.format(fake_asset, "ID"))))
for index, asset in enumerate(self.search_result, 1): for index, asset in enumerate(self.search_result, 1):
self.client.send(wr(line.format(asset, index))) self.client.send(wr(line.format(asset, index)))
self.client.send(wr("Total: {}".format(len(self.search_result)), before=1)) self.client.send(wr(_("Total: {}").format(len(self.search_result)), before=1))
def search_and_display(self, q): def search_and_display(self, q):
self.search_assets(q) self.search_assets(q)
...@@ -209,14 +210,39 @@ class InteractiveServer: ...@@ -209,14 +210,39 @@ class InteractiveServer:
thread.start() thread.start()
def choose_system_user(self, system_users): def choose_system_user(self, system_users):
pass if len(system_users) == 1:
return system_users[0]
elif len(system_users) == 0:
return None
def search_and_proxy(self, opt, from_result=False): while True:
asset = Asset(id=1, hostname="testserver", ip="123.57.183.135", port=8022) self.client.send(wr(_("Choose one to login: ")))
system_user = SystemUser(id=2, username="web", password="redhat123", name="web") self.display_system_users(system_users)
self.proxy(asset, system_user) opt = self.get_choice("ID> ")
if opt.isdigit() and len(system_users) > int(opt):
return system_users[int(opt)]
elif opt in ['q', 'Q']:
break
else:
for system_user in system_users:
if system_user.username == opt:
return system_user
def display_system_users(self, system_users):
for index, system_user in enumerate(system_users):
self.client.send(wr("{} {}".format(index, system_user.username)))
def search_and_proxy(self, opt):
self.search_assets(opt)
if len(self.search_result) == 1:
self.proxy(self.search_result[0])
else:
self.display_search_result()
def proxy(self, asset, system_user): def proxy(self, asset):
system_user = self.choose_system_user(asset.system_users_granted)
if system_user is None:
self.client.send(_("No user"))
forwarder = ProxyServer(self.app, self.client) forwarder = ProxyServer(self.app, self.client)
forwarder.proxy(asset, system_user) forwarder.proxy(asset, system_user)
......
...@@ -10,18 +10,16 @@ import base64 ...@@ -10,18 +10,16 @@ import base64
import calendar import calendar
import time import time
import datetime import datetime
import gettext
from io import StringIO from io import StringIO
import paramiko import paramiko
import pyte import pyte
import pytz import pytz
from email.utils import formatdate from email.utils import formatdate
from queue import Queue, Empty
BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
try:
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty
def ssh_key_string_to_obj(text): def ssh_key_string_to_obj(text):
...@@ -348,4 +346,19 @@ class MultiQueue(Queue): ...@@ -348,4 +346,19 @@ class MultiQueue(Queue):
return items return items
def _gettext():
gettext.bindtextdomain("coco", os.path.join(BASE_DIR, "locale"))
gettext.textdomain("coco")
return gettext.gettext
def make_message():
os.makedirs(os.path.join(BASE_DIR, "locale", "zh_CN"))
pass
def compile_message():
pass
ugettext = _gettext()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment