diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index b7425b870..6d845f05b 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -221,8 +221,11 @@ class Asset(NodesRelationMixin, AbsConnectivity, JSONFilterMixin, JMSOrgBaseMode return self.address def get_target_ssh_port(self): - protocol = self.protocols.all().filter(name='ssh').first() - return protocol.port if protocol else 22 + return self.get_protocol_port('ssh') + + def get_protocol_port(self, protocol): + protocol = self.protocols.all().filter(name=protocol).first() + return protocol.port if protocol else 0 @property def is_valid(self): diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index e805069d2..e424fe7e3 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -126,12 +126,16 @@ class RDPFileClientProtocolURLMixin: return filename, content @staticmethod - def get_connect_filename(prefix_name): - prefix_name = prefix_name.replace('/', '_') - prefix_name = prefix_name.replace('\\', '_') - prefix_name = prefix_name.replace('.', '_') + def escape_name(name): + name = name.replace('/', '_') + name = name.replace('\\', '_') + name = name.replace('.', '_') + name = urllib.parse.quote(name) + return name + + def get_connect_filename(self, prefix_name): filename = f'{prefix_name}-jumpserver' - filename = urllib.parse.quote(filename) + filename = self.escape_name(filename) return filename @staticmethod @@ -145,28 +149,29 @@ class RDPFileClientProtocolURLMixin: connect_method_dict = ConnectMethodUtil.get_connect_method( token.connect_method, token.protocol, _os ) + asset = token.asset if connect_method_dict is None: raise ValueError('Connect method not support: {}'.format(connect_method_name)) - endpoint = self.get_smart_endpoint( - protocol=connect_method_dict['endpoint_protocol'], - asset=token.asset - ) + account = token.account or token.input_username + datetime = timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H:%M:%S') + name = account + '@' + str(asset) + '[' + datetime + ']' data = { - 'id': str(token.id), - 'name': f'{endpoint.host}-{str(token.id)[:18]}', + 'version': 2, + 'id': str(token.id), # 兼容老的,未来几个版本删掉 + 'value': token.value, # 兼容老的,未来几个版本删掉 + 'name': self.escape_name(name), 'protocol': token.protocol, - 'host': endpoint.host, - 'port': endpoint.get_port(token.asset, token.protocol), - 'username': f'JMS-{str(token.id)}', - 'value': token.value, - 'command': '', - 'file': {} + 'token': { + 'id': str(token.id), + 'value': token.value, + }, + 'file': {}, + 'command': '' } if connect_method_name == NativeClient.mstsc or connect_method_dict['type'] == 'applet': filename, content = self.get_rdp_file_info(token) - filename = urllib.parse.unquote(filename) data.update({ 'protocol': 'rdp', 'file': { @@ -175,8 +180,26 @@ class RDPFileClientProtocolURLMixin: } }) else: - cmd = NativeClient.get_launch_command(connect_method_name, token, endpoint) - data.update({'command': cmd}) + endpoint = self.get_smart_endpoint( + protocol=connect_method_dict['endpoint_protocol'], + asset=asset + ) + data.update({ + 'asset': { + 'id': str(asset.id), + 'category': asset.category, + 'type': asset.type, + 'name': asset.name, + 'address': asset.address, + 'info': { + **asset.spec_info, + } + }, + 'endpoint': { + 'host': endpoint.host, + 'port': endpoint.get_port(token.asset, token.protocol), + } + }) return data def get_smart_endpoint(self, protocol, asset=None): diff --git a/apps/common/management/commands/services/services/flower.py b/apps/common/management/commands/services/services/flower.py index 94dd8e2f0..db859a78a 100644 --- a/apps/common/management/commands/services/services/flower.py +++ b/apps/common/management/commands/services/services/flower.py @@ -1,18 +1,10 @@ -from ..hands import * from .base import BaseService +from ..hands import * __all__ = ['FlowerService'] class FlowerService(BaseService): - - def __init__(self, **kwargs): - super().__init__(**kwargs) - - @property - def db_file(self): - return os.path.join(BASE_DIR, 'data', 'flower.db') - @property def cmd(self): print("\n- Start Flower as Task Monitor") @@ -24,11 +16,9 @@ class FlowerService(BaseService): '-A', 'ops', 'flower', '-logging=info', - '-db={}'.format(self.db_file), '--url_prefix=/core/flower', '--auto_refresh=False', '--max_tasks=1000', - '--persistent=True', '--state_save_interval=600000' ] return cmd diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py index aab6f6c75..c793bb7a1 100644 --- a/apps/terminal/connect_methods.py +++ b/apps/terminal/connect_methods.py @@ -26,34 +26,29 @@ class WebMethod(TextChoices): class NativeClient(TextChoices): # Koko - ssh = 'ssh', 'SSH CLI' - sftp = 'sftp', 'SFTP CLI' - putty = 'putty', 'PuTTY' - xshell = 'xshell', 'Xshell' - + ssh_client = 'ssh_client', _('SSH Client') + ssh_guide = 'ssh_guide', _('SSH Guide') + sftp_client = 'sftp_client', _('SFTP Client') # Magnus + db_guide = 'db_guide', _('DB Guide') db_client = 'db_client', _('DB Client') - # Razor - mstsc = 'mstsc', 'Remote Desktop' + mstsc = 'mstsc', _('Remote Desktop') @classmethod def get_native_clients(cls): # native client 关注的是 endpoint 的 protocol, # 比如 telnet mysql, koko 都支持,到那时暴露的是 ssh 协议 clients = { - Protocol.ssh: { - 'default': [cls.ssh], - 'windows': [cls.putty], - }, - Protocol.sftp: [cls.sftp], + Protocol.ssh: [cls.ssh_client, cls.ssh_guide], + Protocol.sftp: [cls.sftp_client], Protocol.rdp: [cls.mstsc], - Protocol.mysql: [cls.db_client], - Protocol.mariadb: [cls.db_client], - Protocol.redis: [cls.db_client], - Protocol.mongodb: [cls.db_client], - Protocol.oracle: [cls.db_client], - Protocol.postgresql: [cls.db_client], + Protocol.mysql: [cls.db_client, cls.db_guide], + Protocol.mariadb: [cls.db_client, cls.db_guide], + Protocol.redis: [cls.db_client, cls.db_guide], + Protocol.mongodb: [cls.db_client, cls.db_guide], + Protocol.oracle: [cls.db_client, cls.db_guide], + Protocol.postgresql: [cls.db_client, cls.db_guide], } return clients @@ -97,28 +92,6 @@ class NativeClient(TextChoices): }) return methods - @classmethod - def get_launch_command(cls, name, token, endpoint, os='windows'): - username = f'JMS-{token.id}' - commands = { - cls.ssh: f'ssh {username}@{endpoint.host} -p {endpoint.ssh_port}', - cls.sftp: f'sftp {username}@{endpoint.host} -P {endpoint.ssh_port}', - cls.putty: f'putty.exe -ssh {username}@{endpoint.host} -P {endpoint.ssh_port}', - cls.xshell: f'xshell.exe -url ssh://{username}:{token.value}@{endpoint.host}:{endpoint.ssh_port}', - # 前端自己处理了 - # cls.mysql: 'mysql -h {hostname} -P {port} -u {username} -p', - # cls.psql: { - # 'default': 'psql -h {hostname} -p {port} -U {username} -W', - # 'windows': 'psql /h {hostname} /p {port} /U {username} -W', - # }, - # cls.sqlplus: 'sqlplus {username}/{password}@{hostname}:{port}', - # cls.redis: 'redis-cli -h {hostname} -p {port} -a {password}', - } - command = commands.get(name) - if isinstance(command, dict): - command = command.get(os, command.get('default')) - return command - class AppletMethod: @classmethod