diff --git a/jasset/views.py b/jasset/views.py
index 37023353e..0f7cb55b6 100644
--- a/jasset/views.py
+++ b/jasset/views.py
@@ -7,7 +7,7 @@ from jumpserver.models import Setting
from jasset.forms import AssetForm, IdcForm
from jasset.models import Asset, IDC, AssetGroup, ASSET_TYPE, ASSET_STATUS
from jperm.perm_api import get_group_asset_perm
-from jperm.ansible_api import Tasks, MyRunner
+from jperm.ansible_api import MyRunner
from jperm.perm_api import gen_resource
diff --git a/jperm/ansible_api.py b/jperm/ansible_api.py
index 422c65a03..57c01d158 100644
--- a/jperm/ansible_api.py
+++ b/jperm/ansible_api.py
@@ -119,8 +119,8 @@ class MyRunner(MyInventory):
super(MyRunner, self).__init__(*args, **kwargs)
self.results_raw = {}
- def run(self, module_name='shell', module_args='', timeout=10, forks=10, pattern='',
- sudo=False, sudo_user='root', sudo_pass=''):
+ def run(self, module_name='shell', module_args='', timeout=10, forks=10, pattern='*',
+ become=False, become_method='sudo', become_user='root', become_pass=''):
"""
run module from andible ad-hoc.
module_name: ansible module_name
@@ -132,10 +132,10 @@ class MyRunner(MyInventory):
inventory=self.inventory,
pattern=pattern,
forks=forks,
- become=sudo,
- become_method='sudo',
- become_user=sudo_user,
- become_pass=sudo_pass
+ become=become,
+ become_method=become_method,
+ become_user=become_user,
+ become_pass=become_pass
)
self.results_raw = hoc.run()
return self.results_raw
@@ -156,7 +156,7 @@ class MyRunner(MyInventory):
for host, info in contacted.items():
if info.get('failed'):
result['failed'][host] = info.get('msg') + info.get('stderr', '')
- elif info.get('stderr'):
+ elif info.get('stderr') and info.get('module_name') in ['shell', 'command', 'raw']:
result['failed'][host] = info.get('stderr') + str(info.get('warnings'))
else:
result['ok'][host] = info.get('stdout')
@@ -265,60 +265,21 @@ class Command(MyInventory):
return self.results_raw.get("dark")
-class Tasks(Command):
+class MyTask(MyRunner):
"""
this is a tasks object for include the common command.
"""
def __init__(self, *args, **kwargs):
- super(Tasks, self).__init__(*args, **kwargs)
-
- def __run(self,
- module_args,
- module_name="command",
- timeout=5,
- forks=10,
- group='default_group',
- pattern='*',
- ):
- """
- run command from andible ad-hoc.
- command : 必须是一个需要执行的命令字符串, 比如
- 'uname -a'
- """
- hoc = Runner(module_name=module_name,
- module_args=module_args,
- timeout=timeout,
- inventory=self.inventory,
- subset=group,
- pattern=pattern,
- forks=forks,
- become=False,
- )
-
- self.results = hoc.run()
- return {"msg": self.msg, "result": self.results}
-
- @property
- def msg(self):
- """
- get the contacted and dark msg
- """
- msg = {}
- for result in ["contacted", "dark"]:
- all = self.results.get(result)
- for key, value in all.iteritems():
- if value.get("msg"):
- msg[key] = value.get("msg")
- return msg
+ super(MyTask, self).__init__(*args, **kwargs)
def push_key(self, user, key_path):
"""
push the ssh authorized key to target.
"""
module_args = 'user="%s" key="{{ lookup("file", "%s") }}" state=present' % (user, key_path)
- self.__run(module_args, "authorized_key")
+ self.run("authorized_key", module_args, become=True)
- return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"}
+ return self.results
def push_multi_key(self, **user_info):
"""
@@ -345,9 +306,9 @@ class Tasks(Command):
push the ssh authorized key to target.
"""
module_args = 'user="%s" key="{{ lookup("file", "%s") }}" state="absent"' % (user, key_path)
- self.__run(module_args, "authorized_key")
+ self.run("authorized_key", module_args, become=True)
- return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"}
+ return self.results
def add_user(self, username, password=''):
"""
@@ -358,9 +319,9 @@ class Tasks(Command):
module_args = 'name=%s shell=/bin/bash password=%s' % (username, encrypt_pass)
else:
module_args = 'name=%s shell=/bin/bash' % username
- self.__run(module_args, "user")
+ self.run("user", module_args, become=True)
- return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok"}
+ return self.results
def add_multi_user(self, **user_info):
"""
@@ -387,85 +348,10 @@ class Tasks(Command):
"""
delete a host user.
"""
- module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % (username)
- self.__run(module_args,
- "user",)
+ module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % username
+ self.run("user", module_args, become=True)
- return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
-
- def add_init_users(self):
- """
- add initail users: SA, DBA, DEV
- """
- results = {}
- action = results["action_info"] = {}
- users = {"SA": get_rand_pass(), "DBA": get_rand_pass(), "DEV": get_rand_pass()}
- for user, password in users.iteritems():
- ret = self.add_user(user, password)
- action[user] = ret
- results["user_info"] = users
-
- return results
-
- def del_init_users(self):
- """
- delete initail users: SA, DBA, DEV
- """
- results = {}
- action = results["action_info"] = {}
- for user in ["SA", "DBA", "DEV"]:
- ret = self.del_user(user)
- action[user] = ret
- return results
-
- def get_host_info(self):
- """
- use the setup module get host informations
- :return:
- all_ip is list
- processor_count is int
- system_dist_version is string
- system_type is string
- disk is dict (device_name: device_size}
- system_dist is string
- processor_type is string
- default_ip is string
- hostname is string
- product_sn is string
- memory_total is int (MB)
- default_mac is string
- product_name is string
- """
- self.__run('', 'setup')
-
- result = {}
- all = self.results.get("contacted")
- for key, value in all.iteritems():
- setup =value.get("ansible_facts")
- # get disk informations
- disk_all = setup.get("ansible_devices")
- disk_need = {}
- for disk_name, disk_info in disk_all.iteritems():
- if disk_name.startswith('sd') or disk_name.startswith('hd'):
- disk_need[disk_name] = disk_info.get("size")
-
- result[key] = {
- "all_ip": setup.get("ansible_all_ipv4_addresses"),
- "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"),
- "processor_type": ' '.join(setup.get("ansible_processor")),
- "processor_count": setup.get("ansible_processor_count"),
- "memory_total": setup.get("ansible_memtotal_mb"),
- "disk": disk_need,
- "system_type": setup.get("ansible_system"),
- "system_dist": setup.get("ansible_distribution"),
- "system_dist_verion": setup.get("ansible_distribution_major_version"),
- "product_sn": setup.get("ansible_product_serial")
- }
-
- return {"failed": self.msg, "ok": result}
+ return self.results
def push_sudo_file(self, file_path):
"""
@@ -473,8 +359,9 @@ class Tasks(Command):
:return:
"""
module_args1 = file_path
- ret = self.__run(module_args1, "script")
- return ret
+ self.run("script", module_args1, become=True)
+ print self.results_raw
+ return self.results
class CustomAggregateStats(callbacks.AggregateStats):
diff --git a/jperm/perm_api.py b/jperm/perm_api.py
index 7366ea284..224d6d2a5 100644
--- a/jperm/perm_api.py
+++ b/jperm/perm_api.py
@@ -296,28 +296,12 @@ def get_role_push_host(role):
asset_all = Asset.objects.all()
asset_pushed = {}
for push in pushs:
- print push.result
asset_pushed[push.asset] = {'success': push.success, 'key': push.is_public_key, 'password': push.is_password,
'result': push.result}
asset_no_push = set(asset_all) - set(asset_pushed.keys())
- print asset_no_push, asset_pushed
return asset_pushed, asset_no_push
-@require_role('user')
-def perm_role_get(request):
- asset_id = request.GET.get('id', 0)
- if asset_id:
- asset = get_object(Asset, id=asset_id)
- if asset:
- role = user_have_perm(request.user, asset=asset)
- return HttpResponse(','.join([i.name for i in role]))
- else:
- roles = get_group_user_perm(request.user).get('role').keys()
- return HttpResponse(','.join(i.name for i in roles))
- return HttpResponse('error')
-
-
if __name__ == "__main__":
print get_role_info(1)
diff --git a/jperm/views.py b/jperm/views.py
index 110b36c76..9d8fdc281 100644
--- a/jperm/views.py
+++ b/jperm/views.py
@@ -11,9 +11,8 @@ from jperm.models import PermRole, PermRule, PermSudo, PermPush
from jumpserver.models import Setting
from jperm.utils import updates_dict, gen_keys, get_rand_pass, get_add_sudo_script
-from jperm.ansible_api import Tasks
+from jperm.ansible_api import MyTask
from jperm.perm_api import get_role_info, get_role_push_host
-
from jumpserver.api import my_render, get_object, CRYPTOR
@@ -211,8 +210,6 @@ def perm_rule_delete(request):
# 根据rule_id 取得rule对象
rule_id = request.POST.get("id")
rule_obj = PermRule.objects.get(id=rule_id)
- print rule_id, rule_obj
- print rule_obj.name
rule_obj.delete()
return HttpResponse(u"删除授权规则:%s" % rule_obj.name)
else:
@@ -423,25 +420,18 @@ def perm_role_push(request):
# 调用Ansible API 进行推送
password_push = True if request.POST.get("use_password") else False
key_push = True if request.POST.get("use_publicKey") else False
- task = Tasks(push_resource)
+ task = MyTask(push_resource)
ret = {}
- ret_failed = {}
# 因为要先建立用户,所以password 是必选项,而push key是在 password也完成的情况下的 可选项
- # 1. 以password 方式推送角色
- if password_push:
- ret["password_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password))
- if ret["password_push"].get("status") != "success":
- ret_failed = ret["password_push"].get('msg')
-
- # 2. 以秘钥 方式推送角色
+ # 1. 以秘钥 方式推送角色
if key_push:
- ret["password_push"] = task.add_user(role.name)
- if ret["password_push"].get("status") != "ok":
- ret_failed = ret["password_push"].get('msg')
+ ret["pass_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password))
ret["key_push"] = task.push_key(role.name, os.path.join(role.key_path, 'id_rsa.pub'))
- if ret["key_push"].get("status") != "ok":
- ret_failed = ret["key_push"].get('msg')
+
+ # 2. 推送账号密码
+ elif password_push:
+ ret["pass_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password))
# 3. 推送sudo配置文件
if password_push or key_push:
@@ -451,16 +441,32 @@ def perm_role_push(request):
role_chosen_aliase[role.name] = ','.join(sudo.name for sudo in sudo_alias if sudo.name)
add_sudo_script = get_add_sudo_script(role_chosen_aliase, sudo_alias)
ret['sudo'] = task.push_sudo_file(add_sudo_script)
-
- if ret['sudo'].get('msg'):
- ret_failed = ret['sudo'].get('msg')
os.remove(add_sudo_script)
logger.debug('推送role结果: %s' % ret)
- logger.debug('推送role错误: %s' % ret_failed)
+ success_asset = {}
+ failed_asset = {}
+ logger.debug(ret)
+ for push_type, result in ret.items():
+ if result.get('failed'):
+ for hostname, info in result.get('failed').items():
+ if hostname in failed_asset.keys():
+ if info in failed_asset.get(hostname):
+ failed_asset[hostname] += info
+ else:
+ failed_asset[hostname] = info
+
+ for push_type, result in ret.items():
+ if result.get('ok'):
+ for hostname, info in result.get('ok').items():
+ if hostname in failed_asset.keys():
+ continue
+ elif hostname in success_asset.keys():
+ if str(info) in success_asset.get(hostname, ''):
+ success_asset[hostname] += str(info)
+ else:
+ success_asset[hostname] = str(info)
- success_asset = []
- failed_asset = []
# 推送成功 回写push表
for asset in calc_assets:
push_check = PermPush.objects.filter(role=role, asset=asset)
@@ -470,20 +476,18 @@ def perm_role_push(request):
def func(**kwargs):
PermPush(**kwargs).save()
- if ret_failed.get(asset.hostname):
- failed_asset.append(asset)
+ if failed_asset.get(asset.hostname):
func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=False,
- result=ret_failed.get(asset.hostname))
+ result=failed_asset.get(asset.hostname))
else:
- success_asset.append(asset)
func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=True)
if not failed_asset:
- msg = u'角色 %s 推送成功[ %s ]' % (role.name, ','.join([asset.hostname for asset in success_asset]))
+ msg = u'角色 %s 推送成功[ %s ]' % (role.name, ','.join(success_asset.keys()))
else:
error = u'角色 %s 推送失败 [ %s ], 推送成功 [ %s ]' % (role.name,
- ','.join([asset.hostname for asset in failed_asset]),
- ','.join([asset.hostname for asset in success_asset]))
+ ','.join(failed_asset.keys()),
+ ','.join(success_asset.keys()))
return my_render('jperm/perm_role_push.html', locals(), request)
@@ -586,11 +590,29 @@ def perm_sudo_delete(request):
def perm_role_recycle(request):
role_id = request.GET.get('role_id')
asset_ids = request.GET.get('asset_id').split(',')
+ assets = []
for asset_id in asset_ids:
asset = get_object(Asset, id=asset_id)
+ assets.append(asset)
role = get_object(PermRole, id=role_id)
PermPush.objects.filter(asset=asset, role=role).delete()
+
+ res = gen_resource(assets)
+ task = MyTask(res)
+
return HttpResponse('删除成功')
+@require_role('user')
+def perm_role_get(request):
+ asset_id = request.GET.get('id', 0)
+ if asset_id:
+ asset = get_object(Asset, id=asset_id)
+ if asset:
+ role = user_have_perm(request.user, asset=asset)
+ return HttpResponse(','.join([i.name for i in role]))
+ else:
+ roles = get_group_user_perm(request.user).get('role').keys()
+ return HttpResponse(','.join(i.name for i in roles))
+ return HttpResponse('error')
diff --git a/jumpserver/views.py b/jumpserver/views.py
index dfa312819..ed144bdf6 100644
--- a/jumpserver/views.py
+++ b/jumpserver/views.py
@@ -302,8 +302,6 @@ def upload(request):
illegal_asset = set(asset_select).issubset(set(assets))
return HttpResponse('没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset]))
-
-
for upload_file in upload_files:
file_path = '%s/%s' % (upload_dir, upload_file.name)
with open(file_path, 'w') as f:
@@ -320,11 +318,11 @@ def upload(request):
filename=' '.join([f.name for f in upload_files]), type='upload', remote_ip=remote_ip,
result=ret).save()
if ret.get('failed'):
- error = '上传目录: %s
上传失败: [ %s ]
上传成功 [ %s ]' % (upload_dir,
+ error = u'上传目录: %s
上传失败: [ %s ]
上传成功 [ %s ]' % (upload_dir,
', '.join(ret.get('failed').keys()),
', '.join(ret.get('ok').keys()))
return HttpResponse(error, status=500)
- msg = '上传目录: %s
传送成功 [ %s ]' % (upload_dir, ', '.join(ret.get('ok')).keys())
+ msg = u'上传目录: %s
传送成功 [ %s ]' % (upload_dir, ', '.join(ret.get('ok').keys()))
return HttpResponse(msg)
return my_render('upload.html', locals(), request)
@@ -345,7 +343,7 @@ def download(request):
if not set(asset_select).issubset(set(assets)):
illegal_asset = set(asset_select).issubset(set(assets))
- return HttpResponse('没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset]))
+ return HttpResponse(u'没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset]))
res = gen_resource({'user': user, 'asset': asset_select})
runner = MyRunner(res)
diff --git a/templates/jasset/asset_add.html b/templates/jasset/asset_add.html
index ac7b9e71c..74efb345d 100644
--- a/templates/jasset/asset_add.html
+++ b/templates/jasset/asset_add.html
@@ -76,9 +76,9 @@