diff --git a/README.md b/README.md index 3e3f207ff..e4c2f5ae3 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ #欢迎使用Jumpserver **Jumpserver** 是一款由python编写开源的跳板机(堡垒机)系统,实现了跳板机应有的功能。基于ssh协议来管理,客户端无需安装agent。 支持常见系统: - 1. redhat centos - 2. debian - 3. suse ubuntu - 4. freebsd + 1. CentOS, RedHat, Fedora, Amazon Linux + 2. Debian + 3. SUSE, Ubuntu + 4. FreeBSD 5. 其他ssh协议硬件设备 ###截图: diff --git a/connect.py b/connect.py index bb4924ddd..c23c33356 100755 --- a/connect.py +++ b/connect.py @@ -436,8 +436,11 @@ class Nav(object): """ def __init__(self, user): self.user = user - self.search_result = {} - self.user_perm = {} + self.search_result = None + self.user_perm = get_group_user_perm(self.user) + self.perm_assets = sorted(self.user_perm.get('asset', []).keys(), + key=lambda x: [int(num) for num in x.ip.split('.') if num.isdigit()]) + self.perm_asset_groups = self.user_perm.get('asset_group', []) @staticmethod def print_nav(): @@ -460,46 +463,83 @@ class Nav(object): """ print textwrap.dedent(msg) - def search(self, str_r=''): + def get_asset_group_member(self, str_r): gid_pattern = re.compile(r'^g\d+$') - # 获取用户授权的所有主机信息 - if not self.user_perm: - self.user_perm = get_group_user_perm(self.user) - user_asset_all = self.user_perm.get('asset').keys() - # 搜索结果保存 - user_asset_search = [] - if str_r: - # 资产组组id匹配 - if gid_pattern.match(str_r): - gid = int(str_r.lstrip('g')) - # 获取资产组包含的资产 - asset_group = get_object(AssetGroup, id=gid) - if asset_group: - user_asset_search = asset_group.asset_set.all() - else: - color_print('没有该资产组或没有权限') - return + if gid_pattern.match(str_r): + gid = int(str_r.lstrip('g')) + # 获取资产组包含的资产 + asset_group = get_object(AssetGroup, id=gid) + if asset_group: + self.search_result = list(asset_group.asset_set.all()) else: + color_print('没有该资产组或没有权限') + return + + def search(self, str_r=''): + # 搜索结果保存 + if str_r: + try: + id_ = int(str_r) + if id_ < len(self.search_result): + self.search_result = [self.search_result[id_]] + return + else: + raise ValueError + + except (ValueError, TypeError): # 匹配 ip, hostname, 备注 - for asset in user_asset_all: - if str_r in asset.ip or str_r in str(asset.hostname) or str_r in str(asset.comment): - user_asset_search.append(asset) + self.search_result = [asset for asset in self.perm_assets if str_r in str(asset.ip) + or str_r in str(asset.hostname) or str_r in str(asset.comment)] else: # 如果没有输入就展现所有 - user_asset_search = user_asset_all + self.search_result = self.perm_assets - self.search_result = dict(zip(range(len(user_asset_search)), user_asset_search)) + def print_search_result(self): color_print('[%-3s] %-12s %-15s %-5s %-10s %s' % ('ID', '主机名', 'IP', '端口', '系统用户', '备注'), 'title') - for index, asset in self.search_result.items(): - # 获取该资产信息 - asset_info = get_asset_info(asset) - # 获取该资产包含的角色 - role = [str(role.name) for role in self.user_perm.get('asset').get(asset).get('role')] - print '[%-3s] %-15s %-15s %-5s %-10s %s' % (index, asset.hostname, asset.ip, asset_info.get('port'), - role, asset.comment) + if hasattr(self.search_result, '__iter__'): + for index, asset in enumerate(self.search_result): + # 获取该资产信息 + asset_info = get_asset_info(asset) + # 获取该资产包含的角色 + role = [str(role.name) for role in self.user_perm.get('asset').get(asset).get('role')] + print '[%-3s] %-15s %-15s %-5s %-10s %s' % (index, asset.hostname, asset.ip, asset_info.get('port'), + role, asset.comment) print + def try_connect(self): + try: + asset = self.search_result[0] + roles = list(self.user_perm.get('asset').get(asset).get('role')) + if len(roles) == 1: + role = roles[0] + elif len(roles) > 1: + print "\033[32m[ID] 系统用户\033[0m" + for index, role in enumerate(roles): + print "[%-2s] %s" % (index, role.name) + print + print "授权系统用户超过1个,请输入ID, q退出" + try: + role_index = raw_input("\033[1;32mID>:\033[0m ").strip() + if role_index == 'q': + return + else: + role = roles[int(role_index)] + except IndexError: + color_print('请输入正确ID', 'red') + return + else: + color_print('没有映射用户', 'red') + return + + ssh_tty = SshTty(login_user, asset, role) + print('Connecting %s ...' % asset.hostname) + ssh_tty.connect() + except (KeyError, ValueError): + color_print('请输入正确ID', 'red') + except ServerError, e: + color_print(e, 'red') + def print_asset_group(self): """ 打印用户授权的资产组 @@ -515,9 +555,6 @@ class Nav(object): 批量执行命令 """ while True: - if not self.user_perm: - self.user_perm = get_group_user_perm(self.user) - roles = self.user_perm.get('role').keys() if len(roles) > 1: # 授权角色数大于1 color_print('[%-2s] %-15s' % ('ID', '系统用户'), 'info') @@ -587,8 +624,6 @@ class Nav(object): def upload(self): while True: - if not self.user_perm: - self.user_perm = get_group_user_perm(self.user) try: print "进入批量上传模式" print "请输入主机名或ansible支持的pattern, 多个主机:分隔 q退出" @@ -640,8 +675,6 @@ class Nav(object): def download(self): while True: - if not self.user_perm: - self.user_perm = get_group_user_perm(self.user) try: print "进入批量下载模式" print "请输入主机名或ansible支持的pattern, 多个主机:分隔,q退出" @@ -723,9 +756,14 @@ def main(): sys.exit(0) if option in ['P', 'p', '\n', '']: nav.search() + nav.print_search_result() continue - if option.startswith('/') or gid_pattern.match(option): + if option.startswith('/'): nav.search(option.lstrip('/')) + nav.print_search_result() + elif gid_pattern.match(option): + nav.get_asset_group_member(str_r=option) + nav.print_search_result() elif option in ['G', 'g']: nav.print_asset_group() continue @@ -741,36 +779,12 @@ def main(): elif option in ['Q', 'q', 'exit']: sys.exit() else: - try: - asset = nav.search_result[int(option)] - roles = nav.user_perm.get('asset').get(asset).get('role') - if len(roles) > 1: - role_check = dict(zip(range(len(roles)), roles)) - print "\033[32m[ID] 系统用户\033[0m" - for index, role in role_check.items(): - print "[%-2s] %s" % (index, role.name) - print - print "授权系统用户超过1个,请输入ID, q退出" - try: - role_index = raw_input("\033[1;32mID>:\033[0m ").strip() - if role_index == 'q': - continue - else: - role = role_check[int(role_index)] - except IndexError: - color_print('请输入正确ID', 'red') - continue - elif len(roles) == 1: - role = list(roles)[0] - else: - color_print('没有映射用户', 'red') - continue - ssh_tty = SshTty(login_user, asset, role) - ssh_tty.connect() - except (KeyError, ValueError): - color_print('请输入正确ID', 'red') - except ServerError, e: - color_print(e, 'red') + nav.search(option) + if len(nav.search_result) == 1: + nav.try_connect() + else: + nav.print_search_result() + except IndexError, e: color_print(e) time.sleep(5) diff --git a/install/install.py b/install/install.py index 01b281a92..da26157a5 100755 --- a/install/install.py +++ b/install/install.py @@ -80,12 +80,12 @@ class PreSetup(object): self.ip = '' self.key = ''.join(random.choice(string.ascii_lowercase + string.digits) \ for _ in range(16)) - self.dist = platform.dist()[0].lower() - self.version = platform.dist()[1] + self.dist = platform.linux_distribution(supported_dists=['system'])[0].lower() + self.version = platform.linux_distribution(supported_dists=['system'])[1] @property def _is_redhat(self): - if self.dist == "centos" or self.dist == "redhat" or self.dist == "fedora": + if self.dist == "centos" or self.dist == "redhat" or self.dist == "fedora" or self.dist == "amazon linux ami": return True @property @@ -105,7 +105,7 @@ class PreSetup(object): def check_platform(self): if not (self._is_redhat or self._is_ubuntu): - print(u"支持的平台: CentOS, RedHat, Fedora, Debian, Ubuntu, 暂不支持其他平台安装.") + print(u"支持的平台: CentOS, RedHat, Fedora, Debian, Ubuntu, Amazon Linux, 暂不支持其他平台安装.") exit() @staticmethod diff --git a/templates/setting.html b/templates/setting.html index d13cf7f4f..061a71f0e 100644 --- a/templates/setting.html +++ b/templates/setting.html @@ -109,7 +109,7 @@ timely: 2, theme: "yellow_right_effect", rules: { - check_name: [/^\w{2,20}$/, '大小写字母数字和下划线,2-20位'], + check_name: [/^(\w|\-){2,20}$/, '大小写字母、数字、中划线和下划线,2-20位'], check_port: [/^\d{1,5}$/, '端口号不正确'], either: function(){ return $('#password').val() == ''