完成登陆,批量执行命令流

pull/26/head
ibuler 2015-11-21 19:20:11 +08:00
parent 877383679c
commit 93481a98db
6 changed files with 118 additions and 49 deletions

View File

@ -19,8 +19,9 @@ import struct, fcntl, signal, socket, select
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
if django.get_version() != '1.6':
django.setup()
from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object, mkdir
from jumpserver.api import logger, Log, TtyLog
from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object, mkdir, get_asset_info, get_role
from jumpserver.api import logger, Log, TtyLog, get_role_key
from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm
from jumpserver.settings import LOG_DIR
from jperm.ansible_api import Command
@ -73,15 +74,15 @@ class Tty(object):
A virtual tty class
一个虚拟终端类实现连接ssh和记录日志基类
"""
def __init__(self, username, asset_name):
self.username = username
self.asset_name = asset_name
def __init__(self, user, asset, role):
self.username = user.username
self.asset_name = asset.hostname
self.ip = None
self.port = 22
self.channel = None
#self.asset = get_object(Asset, name=asset_name)
#self.user = get_object(User, username=username)
self.role = None
self.asset = asset
self.user = user
self.role = role
self.ssh = None
self.connect_info = None
self.login_type = 'ssh'
@ -287,7 +288,10 @@ class Tty(object):
# 2. get 映射用户
# 3. get 映射用户的账号密码或者key
# self.connect_info = {'user': '', 'asset': '', 'ip': '', 'port': 0, 'role_name': '', 'role_pass': '', 'role_key': ''}
self.connect_info = {'user': 'a', 'asset': 'b', 'ip': '127.0.0.1', 'port': 22, 'role_name': 'root', 'role_pass': 'redhat', 'role_key': ''}
asset_info = get_asset_info(self.asset)
self.connect_info = {'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'),
'port': int(asset_info.get('port')), 'role_name': self.role.name,
'role_pass': self.role.password, 'role_key': self.role.key_path}
return self.connect_info
def get_connection(self):
@ -301,7 +305,7 @@ class Tty(object):
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
role_key = connect_info.get('role_key')
role_key = get_role_key(self.user, self.role)
if role_key and os.path.isfile(role_key):
try:
ssh.connect(connect_info.get('ip'),
@ -469,6 +473,7 @@ class Nav(object):
def __init__(self, user):
self.user = user
self.search_result = {}
self.user_perm = {}
@staticmethod
def print_nav():
@ -499,7 +504,9 @@ class Nav(object):
def search(self, str_r=''):
gid_pattern = re.compile(r'^g\d+$')
user_asset_all = list(Asset.objects.all())
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:
if gid_pattern.match(str_r):
@ -512,13 +519,15 @@ class Nav(object):
user_asset_search = user_asset_all
self.search_result = dict(zip(range(len(user_asset_search)), user_asset_search))
print '\033[32m[%-3s] %-15s %-15s %-5s %-5s %s \033[0m' % ('ID', 'AssetName', 'IP', 'Port', 'Role', 'Comment')
print '\033[32m[%-3s] %-15s %-15s %-5s %-10s %s \033[0m' % ('ID', 'AssetName', 'IP', 'Port', 'Role', 'Comment')
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')]
if asset.comment:
print '[%-3s] %-15s %-15s %-5s %-5s %s' % (index, 'asset_name'+str(index), asset.ip, asset.port, 'role', asset.comment)
print '[%-3s] %-15s %-15s %-5s %-10s %s' % (index, asset.hostname, asset.ip, asset_info.get('port'),
role, asset.comment)
else:
print '[%-3s] %-15s %-15s %-5s %-5s' % (index, 'asset_name'+str(index), asset.ip, asset.port, 'role')
print '[%-3s] %-15s %-15s %-5s %-10s' % (index, asset.hostname, asset.ip, asset_info.get('port'), role)
print
@staticmethod
@ -542,13 +551,11 @@ class Nav(object):
if pattern == 'q':
break
else:
res = {
"group1": {
"hosts": [{"hostname": "127.0.0.1", "port": "22", "username": "lastimac", "password": "redhat"}, {"hostname": "192.168.244.129", "port": "22", "username": "root", "password": "redhat"}, {"hostname": "j", "port": "22", "username": "root", "password": "redhat"}],
"vars": {"var1": 'a', "var2": 'a'}
}
}
if not self.user_perm:
self.user_perm = get_group_user_perm(self.user)
res = gen_resource(self.user, perm=self.user_perm)
cmd = Command(res)
logger.debug(res)
for inv in cmd.inventory.get_hosts(pattern=pattern):
print inv.name
confirm_host = raw_input("\033[1;32mIs that [y/n]>:\033[0m ").strip()
@ -617,7 +624,28 @@ def main():
else:
try:
asset = nav.search_result[int(option)]
ssh_tty = SshTty('a', 'b')
roles = get_role(login_user, asset)
if len(roles) > 1:
role_check = dict(zip(range(len(roles)), roles))
print role_check
for index, role in role_check.items():
print "[%s] %s" % (index, role.name)
print "输入角色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 = roles[0]
else:
color_print('没有映射用户', 'red')
continue
ssh_tty = SshTty(login_user, asset, role)
ssh_tty.connect()
except (KeyError, ValueError):
color_print('请输入正确ID', 'red')

View File

@ -404,7 +404,7 @@ class Tasks(Command):
result[key] = {
"all_ip": setup.get("ansible_all_ipv4_addresses"),
"hostname" : setup.get("ansible_hostname" ),
"hostname" : setup.get("ansible_hostname"),
"default_ip": setup.get("ansible_default_ipv4").get("address"),
"default_mac": setup.get("ansible_default_ipv4").get("macaddress"),
"product_name": setup.get("ansible_product_name"),

View File

@ -132,37 +132,30 @@ def get_group_asset_perm(ob):
return perm
def gen_resource(ob):
def gen_resource(ob, perm=None):
"""
ob为用户或资产列表或资产queryset
生成MyInventory需要的 resource文件
"""
res = []
if isinstance(ob, User):
perm = get_group_user_perm(ob)
if not perm:
perm = get_group_user_perm(ob)
for asset, asset_info in perm.get('asset').items():
info = {'hostname': asset.hostname, 'ip': asset.ip, 'port': asset.port}
asset_info = get_asset_info(asset)
info = {'hostname': asset.hostname, 'ip': asset.ip, 'port': asset_info.get('port', 22)}
try:
role = sorted(list(asset_info.get('role')))[0]
role = sorted(list(perm.get('asset').get(asset).get('role')))[0]
except IndexError:
continue
info['username'] = role.name
info['password'] = role.password
info['key_path'] = role.key_path
info['ssh_key'] = get_role_key(ob, role)
res.append(info)
elif isinstance(ob, (list, QuerySet)):
default = get_object(Setting, name='default')
for asset in ob:
info = {'hostname': asset.hostname, 'ip': asset.ip}
if asset.use_default_auth:
if default:
info['port'] = default.default_port
info['username'] = default.default_user
info['password'] = default.default_password
info['ssh_key'] = default.default_pri_key_path
else:
info['port'] = asset.port
info['username'] = asset.username
info = get_asset_info(asset)
res.append(info)
return res

View File

@ -51,6 +51,7 @@ def gen_keys():
private_key = os.path.join(key_path_dir, 'id_rsa')
public_key = os.path.join(key_path_dir, 'id_rsa.pub')
key.write_private_key_file(private_key)
os.chmod(private_key, 0644)
with open(public_key, 'w') as content_file:
for data in [key.get_name(),

View File

@ -9,19 +9,21 @@ import hashlib
import datetime
import random
import subprocess
from settings import *
import json
import logging
from settings import *
from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.http import HttpResponse, Http404
from django.template import RequestContext
from juser.models import User, UserGroup
from jlog.models import Log, TtyLog
from jasset.models import Asset, AssetGroup
from jperm.models import PermRule, PermRole
from jumpserver.models import Setting
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.mail import send_mail
import json
import logging
def set_log(level):
@ -45,11 +47,57 @@ def set_log(level):
return logger_f
def chown(path, user, group='', ):
def get_asset_info(asset):
default = get_object(Setting, name='default')
info = {'hostname': asset.hostname, 'ip': asset.ip}
if asset.use_default_auth:
if default:
info['port'] = default.default_port
info['username'] = default.default_user
info['password'] = CRYPTOR.decrypt(default.default_password)
info['ssh_key'] = default.default_pri_key_path
else:
info['port'] = asset.port
info['username'] = asset.username
info['password'] = asset.password
return info
def get_role(user, asset):
roles = []
rules = PermRule.objects.filter(user=user, asset=asset)
for rule in rules:
roles.extend(list(rule.role.all()))
return roles
def get_role_key(user, role):
"""
由于role的key的权限是所有人可以读的 ansible要求为600所以拷贝一份到特殊目录
:param user:
:param role:
:return: self key path
"""
user_role_key_dir = os.path.join(KEY_DIR, 'user')
user_role_key_path = os.path.join(user_role_key_dir, '%s_%s.pem' % (user.username, role.name))
mkdir(user_role_key_dir, mode=777)
if not os.path.isfile(user_role_key_path):
with open(os.path.join(role.key_path, 'id_rsa')) as fk:
with open(user_role_key_path, 'w') as fu:
fu.write(fk.read())
print user_role_key_path, user.username
chown(user_role_key_path, user.username)
os.chmod(user_role_key_path, 0600)
return user_role_key_path
def chown(path, user, group=''):
if not group:
group = user
uid = pwd.getpwnam(user).pwd_uid
gid = pwd.getpwnam(group).gr_gid
uid = pwd.getpwnam(user).pw_uid
gid = pwd.getpwnam(group).pwd_gid
os.chown(path, uid, gid)
@ -170,8 +218,7 @@ class PyCrypt(object):
try:
plain_text = cryptor.decrypt(a2b_hex(text))
except TypeError:
# raise ServerError('Decrypt password error, TYpe error.')
pass
raise ServerError('Decrypt password error, TYpe error.')
return plain_text.rstrip('\0')
@ -406,7 +453,7 @@ def mkdir(dir_name, username='', mode=0755):
"""
if not os.path.isdir(dir_name):
os.makedirs(dir_name)
os.chmod(dir_name, mode)
os.chmod(dir_name, mode)
if username:
chown(dir_name, username)

View File

@ -130,7 +130,7 @@ def gen_ssh_key(username, password='',
"""
logger.debug('生成ssh key 并设置authorized_keys')
private_key_file = os.path.join(key_dir, username)
mkdir(key_dir)
mkdir(key_dir, mode=777)
if os.path.isfile(private_key_file):
os.unlink(private_key_file)
ret = bash('echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password))