def send_email(email_config, email_title, email_to, email_msg): """ 发送邮件 """ rest = {'msgCode': 0, 'msgError': ''} # msgCode: 0:成功 1:失败 message = MIMEText(email_msg, 'plain', 'utf-8') message['Subject'] = Header(email_title) message['From'] = email_config.email_username emali_list = ','.join(email_to) message['To'] = emali_list server = smtplib.SMTP() if email_config.email_use_ssl: server = smtplib.SMTP_SSL() try: server.connect(email_config.smtp_server, email_config.smtp_server_port) if email_config.email_use_tls and email_config.email_use_ssl is not True: server.starttls() logger.info(u'%s: password %s' % (email_config.name, email_config.email_password)) server.login(email_config.email_username, CRYPTOR.decrypt(email_config.email_password)) server.sendmail(email_config.email_username, email_to, message.as_string()) except Exception as e: rest['msgCode'] = 1 rest['msgError'] = e logger.error(e) finally: server.quit() return rest
def send_email(email_config, email_title, email_to, email_msg): """ 发送邮件 """ rest = {'msgCode': 0, 'msgError': ''} # msgCode: 0:成功 1:失败 message = MIMEText(email_msg, 'plain', 'utf-8') message['Subject'] = Header(email_title) message['From'] = email_config.email_username emali_list = ','.join(email_to) message['To'] = emali_list server = smtplib.SMTP() if email_config.email_use_ssl: server = smtplib.SMTP_SSL() try: server.connect(email_config.smtp_server, email_config.smtp_server_port) if email_config.email_use_tls and email_config.email_use_ssl is not True: server.starttls() logger.info(u'%s: password %s'%(email_config.name, email_config.email_password)) server.login(email_config.email_username, CRYPTOR.decrypt(email_config.email_password)) server.sendmail(email_config.email_username, email_to, message.as_string()) except Exception as e: rest['msgCode'] = 1 rest['msgError'] = e logger.error(e) finally: server.quit() return rest
def push_role_to_asset(asset_list, role, username, proxy=None): """from permManage.ansible_api import MyTask 推送系统用户到远程主机上 """ try: proxy_assets = Asset.objects.filter(proxy__proxy_name=proxy.proxy_name) need_push_assets = list(set(asset_list) & set(proxy_assets)) push_resource = gen_resource(need_push_assets) # TODO 调用Ansible API 进行推送 host_list = [asset.networking.all()[0].ip_address for asset in need_push_assets] host_names = [asset.name for asset in need_push_assets] if host_list: task = MyTask(push_resource, host_list) ret = {} # 因为要先建立用户,而push key是在 password也完成的情况下的可选项 # 1. 以秘钥 方式推送角色 role_proxy = get_one_or_all('PermRole', proxy, role.uuid_id) ret["pass_push"] = task.add_user(role.name, proxy, role.system_groups, username) time.sleep(1) # 暂停1秒,保证用户创建完成之后再推送key ret["key_push"] = task.push_key(role.name, os.path.join(role_proxy['key_path'], 'id_rsa.pub'), proxy, username) # 2. 推送账号密码 <为了安全 系统用户统一使用秘钥进行通信,不再提供密码方式的推送> # 3. 推送sudo配置文件 sudo_list = [sudo for sudo in role.sudo.all()] if sudo_list: sudo_uuids = [sudo.uuid_id for sudo in role.sudo.all()] ret['sudo'] = task.push_sudo(role, sudo_uuids, proxy, username) logger.info('推送用户结果ret:%s'%ret) # TODO 将事件放进queue中 event_task_names = [] if ret.has_key('pass_push'): tk_pass_push = ret['pass_push']['task_name'] event_task_names.append(tk_pass_push) if ret.has_key('key_push'): tk_key_push = ret['key_push']['task_name'] event_task_names.append(tk_key_push) if ret.has_key('sudo'): if 'task_name' in ret['sudo']: tk_sudo_push = ret['sudo']['task_name'] event_task_names.append(tk_sudo_push) event = dict(push_assets=host_names, role_name=role.name, password_push=False, key_push=True, task_proxy=proxy.proxy_name) event['tasks'] = event_task_names event['username'] = username task_queue.put(event) # TODO 记录task事件 for item in event['tasks']: tk = Task() tk.task_name = item tk.status = 'running' tk.start_time = datetime.datetime.now() tk.username = username tk.save() except Exception as e: raise ServerError(e)
def query_event(task_name, username, proxy): data = {'task_name': task_name, 'username': username} data = json.dumps(data) api = APIRequest('{0}/v1.0/permission/event'.format(proxy.url), proxy.username, CRYPTOR.decrypt(proxy.password)) result, codes = api.req_post(data) logger.info('推送用户事件查询结果result:%s'%result) return result
def query_event(task_name, username, proxy): data = {'task_name': task_name, 'username': username} data = json.dumps(data) api = APIRequest('{0}/v1.0/permission/event'.format(proxy.url), proxy.username, CRYPTOR.decrypt(proxy.password)) result, codes = api.req_post(data) logger.info('推送用户事件查询结果result:%s' % result) return result
def role_proxy_operator(user_name, obj_name, data, proxy=None, obj_uuid='all', action='add'): """ 保存,更新, 删除数据,并把操作结果保存到Task表中 obj_name: PermRole, PermSudo """ result = res_info = msg_name = '' g_lock = threading.Lock() # 线程锁 if obj_name == 'PermRole': msg_name = u'系统用户' elif obj_name == 'PermSudo': msg_name = u'SUDO别名' g_url = '{0}/v1.0/permission/{1}/{2}'.format(proxy.url, obj_name, obj_uuid) try: g_lock.acquire() # 在每个proxy上(add/update/delete) role/sudo,并返回结果 api = APIRequest(g_url, proxy.username, CRYPTOR.decrypt(proxy.password)) if action == 'add': result, codes = api.req_post(data) pdata = json.loads(data) res_info = u'添加{0}{1} {2}'.format(msg_name, pdata['name'], result['messege']) elif action == 'update': result, codes = api.req_put(data) pdata = json.loads(data) res_info = u'编辑{0}{1} {2}'.format(msg_name, pdata['name'], result['messege']) elif action == 'delete': result, codes = api.req_del(data) pdata = json.loads(data) res_info = u'删除{0}{1} {2}'.format(msg_name, pdata['name'], result['messege']) logger.info('role_proxy_%s:%s'%(action, result['messege'])) # 生成唯一的事件名称,用于从数据库中查询执行结果 if 'name' not in json.dumps(data): raise ValueError('role_proxy_operator: data["name"]不存在') task_name = json.loads(data)['name'] + '_' + uuid.uuid4().hex # 将事件添加到消息队列中 task_queue.put({'server': task_name, 'username': user_name}) # 将执行结果保存到数据库中 role_task = Task() role_task.task_name = task_name role_task.proxy_name = proxy.proxy_name role_task.role_name = json.loads(data)['name'] role_task.username = user_name role_task.status = 'complete' role_task.content = res_info role_task.url = g_url role_task.start_time = datetime.datetime.now() role_task.action = action role_task.role_uuid = obj_uuid role_task.role_data = data role_task.result = result['messege'] role_task.save() except Exception as e: logger.error("[role_proxy_operator] %s"%e) finally: g_lock.release() return result
def perm_role_recycle(request): role_id = request.GET.get('role_id') asset_ids = request.GET.get('asset_id').split(',') # 仅有推送的角色才回收 assets = [get_object(Asset, id=asset_id) for asset_id in asset_ids] recycle_assets = [] for asset in assets: if True in [push.success for push in asset.perm_push.all()]: recycle_assets.append(asset) recycle_resource = gen_resource(recycle_assets) task = MyTask(recycle_resource) try: msg_del_user = task.del_user(get_object(PermRole, id=role_id).name) msg_del_sudo = task.del_user_sudo(get_object(PermRole, id=role_id).name) logger.info("recycle user msg: %s" % msg_del_user) logger.info("recycle sudo msg: %s" % msg_del_sudo) except Exception, e: logger.warning("Recycle Role failed: %s" % e) raise ServerError(u"回收已推送的系统用户失败: %s" % e)
def perm_role_recycle(request): role_id = request.GET.get('role_id') asset_ids = request.GET.get('asset_id').split(',') # 仅有推送的角色才回收 assets = [get_object(Asset, id=asset_id) for asset_id in asset_ids] recycle_assets = [] for asset in assets: if True in [push.success for push in asset.perm_push.all()]: recycle_assets.append(asset) recycle_resource = gen_resource(recycle_assets) task = MyTask(recycle_resource) try: msg_del_user = task.del_user(get_object(PermRole, id=role_id).name) msg_del_sudo = task.del_user_sudo( get_object(PermRole, id=role_id).name) logger.info("recycle user msg: %s" % msg_del_user) logger.info("recycle sudo msg: %s" % msg_del_sudo) except Exception, e: logger.warning("Recycle Role failed: %s" % e) raise ServerError(u"回收已推送的系统用户失败: %s" % e)
else: private_key = key output.write(key) try: key = RSAKey.from_private_key(output) except SSHException, e: raise SSHException(e) for data in [key.get_name(), " ", key.get_base64(), " %s@%s" % ("magicstack", os.uname()[1])]: sbuffer.write(data) public_key = sbuffer.getvalue() key_content['public_key'] = public_key key_content['private_key'] = private_key logger.info('gen_keys: key content:%s'%key_content) return key_content def trans_all(str): if str.strip().lower() == "all": return str.upper() else: return str if __name__ == "__main__": print gen_keys()
def push_role_to_asset(asset_list, role, username, proxy=None): """from permManage.ansible_api import MyTask 推送系统用户到远程主机上 """ try: proxy_assets = Asset.objects.filter(proxy__proxy_name=proxy.proxy_name) need_push_assets = list(set(asset_list) & set(proxy_assets)) push_resource = gen_resource(need_push_assets) # TODO 调用Ansible API 进行推送 host_list = [ asset.networking.all()[0].ip_address for asset in need_push_assets ] host_names = [asset.name for asset in need_push_assets] if host_list: task = MyTask(push_resource, host_list) ret = {} # 因为要先建立用户,而push key是在 password也完成的情况下的可选项 # 1. 以秘钥 方式推送角色 role_proxy = get_one_or_all('PermRole', proxy, role.uuid_id) ret["pass_push"] = task.add_user(role.name, proxy, role.system_groups, username) time.sleep(1) # 暂停1秒,保证用户创建完成之后再推送key ret["key_push"] = task.push_key( role.name, os.path.join(role_proxy['key_path'], 'id_rsa.pub'), proxy, username) # 2. 推送账号密码 <为了安全 系统用户统一使用秘钥进行通信,不再提供密码方式的推送> # 3. 推送sudo配置文件 sudo_list = [sudo for sudo in role.sudo.all()] if sudo_list: sudo_uuids = [sudo.uuid_id for sudo in role.sudo.all()] ret['sudo'] = task.push_sudo(role, sudo_uuids, proxy, username) logger.info('推送用户结果ret:%s' % ret) # TODO 将事件放进queue中 event_task_names = [] if ret.has_key('pass_push'): tk_pass_push = ret['pass_push']['task_name'] event_task_names.append(tk_pass_push) if ret.has_key('key_push'): tk_key_push = ret['key_push']['task_name'] event_task_names.append(tk_key_push) if ret.has_key('sudo'): if 'task_name' in ret['sudo']: tk_sudo_push = ret['sudo']['task_name'] event_task_names.append(tk_sudo_push) event = dict(push_assets=host_names, role_name=role.name, password_push=False, key_push=True, task_proxy=proxy.proxy_name) event['tasks'] = event_task_names event['username'] = username task_queue.put(event) # TODO 记录task事件 for item in event['tasks']: tk = Task() tk.task_name = item tk.status = 'running' tk.start_time = datetime.datetime.now() tk.username = username tk.save() except Exception as e: raise ServerError(e)
def role_proxy_operator(user_name, obj_name, data, proxy=None, obj_uuid='all', action='add'): """ 保存,更新, 删除数据,并把操作结果保存到Task表中 obj_name: PermRole, PermSudo """ result = res_info = msg_name = '' g_lock = threading.Lock() # 线程锁 if obj_name == 'PermRole': msg_name = u'系统用户' elif obj_name == 'PermSudo': msg_name = u'SUDO别名' g_url = '{0}/v1.0/permission/{1}/{2}'.format(proxy.url, obj_name, obj_uuid) try: g_lock.acquire() # 在每个proxy上(add/update/delete) role/sudo,并返回结果 api = APIRequest(g_url, proxy.username, CRYPTOR.decrypt(proxy.password)) if action == 'add': result, codes = api.req_post(data) pdata = json.loads(data) res_info = u'添加{0}{1} {2}'.format(msg_name, pdata['name'], result['messege']) elif action == 'update': result, codes = api.req_put(data) pdata = json.loads(data) res_info = u'编辑{0}{1} {2}'.format(msg_name, pdata['name'], result['messege']) elif action == 'delete': result, codes = api.req_del(data) pdata = json.loads(data) res_info = u'删除{0}{1} {2}'.format(msg_name, pdata['name'], result['messege']) logger.info('role_proxy_%s:%s' % (action, result['messege'])) # 生成唯一的事件名称,用于从数据库中查询执行结果 if 'name' not in json.dumps(data): raise ValueError('role_proxy_operator: data["name"]不存在') task_name = json.loads(data)['name'] + '_' + uuid.uuid4().hex # 将事件添加到消息队列中 task_queue.put({'server': task_name, 'username': user_name}) # 将执行结果保存到数据库中 role_task = Task() role_task.task_name = task_name role_task.proxy_name = proxy.proxy_name role_task.role_name = json.loads(data)['name'] role_task.username = user_name role_task.status = 'complete' role_task.content = res_info role_task.url = g_url role_task.start_time = datetime.datetime.now() role_task.action = action role_task.role_uuid = obj_uuid role_task.role_data = data role_task.result = result['messege'] role_task.save() except Exception as e: logger.error("[role_proxy_operator] %s" % e) finally: g_lock.release() return result
def push_role_event(request): """ 系统用户推送结果查询 """ response = {'error': '', 'message': ''} if request.method == 'GET': if task_queue.qsize() > 0: logger.info(u'任务队列:%s' % task_queue.qsize()) try: tk_event = task_queue.get() if 'server' in tk_event: event_name = tk_event['server'] web_username = tk_event['username'] tk_obj = Task.objects.get(task_name=event_name, username=web_username) if not tk_obj: task_queue.put(tk_event) else: response[ 'message'] = tk_obj.proxy_name + tk_obj.content else: host_names = tk_event.pop('push_assets') calc_assets = [ Asset.objects.get(name=name) for name in host_names ] role = PermRole.objects.get(name=tk_event['role_name']) password_push = tk_event['password_push'] key_push = tk_event['key_push'] proxy = Proxy.objects.get( proxy_name=tk_event['task_proxy']) success_asset = {} failed_asset = {} for task_name in tk_event['tasks']: time.sleep(2) # 暂停3s,否则可能会查不出结果 result = query_event(task_name, tk_event['username'], proxy) if not result: task_queue.put(tk_event) else: # 更新task的status, result tk = get_object(Task, task_name=task_name) tk.status = 'complete' tk.content = result['messege'] tk.save() res = json.loads(result['messege']) if res.get('failed'): for hostname, info in res.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 if res.get('unreachable'): for hostname, info in res.get( 'unreachable').items(): if hostname in failed_asset.keys(): if info in failed_asset.get(hostname): failed_asset[hostname] += info else: failed_asset[hostname] = info if res.get('success'): for hostname, info in res.get( 'success').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) # 推送成功 回写push表 for asset in calc_assets: push_check = PermPush.objects.filter(role=role, asset=asset) if push_check: func = push_check.update else: def func(**kwargs): PermPush(**kwargs).save() if failed_asset.get( asset.networking.all()[0].ip_address): func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=False, result=failed_asset.get( asset.networking.all()[0].ip_address)) else: 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( success_asset.keys())) response['message'] = msg else: intersection = set(success_asset.keys()) & set( failed_asset.keys()) if intersection: for item in intersection: success_asset.pop(item) error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % ( role.name, ','.join(failed_asset.keys()), ','.join(success_asset.keys())) else: error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % ( role.name, ','.join(failed_asset.keys()), ','.join(success_asset.keys())) response['message'] = error except Exception as e: response['message'] = e return HttpResponse(json.dumps(response), content_type='application/json')
for key, value in asset_proxys.items(): proxy = Proxy.objects.filter(proxy_name=key)[0] recycle_resource = gen_resource(value) host_list = [ asset.networking.all()[0].ip_address for asset in value ] task = MyTask(recycle_resource, host_list) try: msg_del_user = task.del_user(role.name, proxy, request.user.username) msg_del_sudo = task.del_user_sudo( role.uuid_id, proxy, request.user.username) except Exception, e: logger.warning(u"Recycle Role failed: %s" % e) raise ServerError(u"回收已推送的系统用户失败: %s" % e) logger.info(u"删除用户 %s - execute delete user: %s" % (role.name, msg_del_user)) logger.info(u"删除用户 %s - execute delete sudo: %s" % (role.name, msg_del_sudo)) # TODO: 判断返回结果,处理异常 # 删除proxy上的role, proxy上的role删除成功后再删除magicstack上的role proxy_list = Proxy.objects.all() data = { 'name': role.name, } data = json.dumps(data) execute_thread_tasks(proxy_list, THREAD_NUMBERS, role_proxy_operator, request.user.username, 'PermRole',
if not role: logger.warning(u"Delete Role: role_id %s not exist" % role_id) raise ServerError(u"role_id %s 无数据记录" % role_id) role_key = role.key_path recycle_assets = [push.asset for push in role.perm_push.all() if push.success] logger.debug(u"delete role %s - delete_assets: %s" % (role.name, recycle_assets)) if recycle_assets: recycle_resource = gen_resource(recycle_assets) task = MyTask(recycle_resource) try: msg_del_user = task.del_user(get_object(PermRole, id=role_id).name) msg_del_sudo = task.del_user_sudo(get_object(PermRole, id=role_id).name) except Exception, e: logger.warning(u"Recycle Role failed: %s" % e) raise ServerError(u"回收已推送的系统用户失败: %s" % e) logger.info(u"delete role %s - execute delete user: %s" % (role.name, msg_del_user)) logger.info(u"delete role %s - execute delete sudo: %s" % (role.name, msg_del_sudo)) # TODO: 判断返回结果,处理异常 # 删除存储的秘钥,以及目录 try: key_files = os.listdir(role_key) for key_file in key_files: os.remove(os.path.join(role_key, key_file)) os.rmdir(role_key) except OSError, e: logger.warning(u"Delete Role: delete key error, %s" % e) raise ServerError(u"删除系统用户key失败: %s" % e) logger.info(u"delete role %s - delete role key directory: %s" % (role.name, role_key)) role.delete() res['content'] = "删除系统用户: %s" % role.name return HttpResponse(u"删除系统用户: %s" % role.name)
def push_role_event(request): """ 系统用户推送结果查询 """ response = {'error': '', 'message':''} if request.method == 'GET': if task_queue.qsize() > 0: logger.info(u'任务队列:%s'%task_queue.qsize()) try: tk_event = task_queue.get() if 'server' in tk_event: event_name = tk_event['server'] web_username = tk_event['username'] tk_obj = Task.objects.get(task_name=event_name, username=web_username) if not tk_obj: task_queue.put(tk_event) else: response['message'] = tk_obj.proxy_name + tk_obj.content else: host_names = tk_event.pop('push_assets') calc_assets = [Asset.objects.get(name=name) for name in host_names] role = PermRole.objects.get(name=tk_event['role_name']) password_push = tk_event['password_push'] key_push = tk_event['key_push'] proxy = Proxy.objects.get(proxy_name=tk_event['task_proxy']) success_asset = {} failed_asset = {} for task_name in tk_event['tasks']: time.sleep(2) # 暂停3s,否则可能会查不出结果 result = query_event(task_name, tk_event['username'], proxy) if not result: task_queue.put(tk_event) else: # 更新task的status, result tk = get_object(Task, task_name=task_name) tk.status = 'complete' tk.content = result['messege'] tk.save() res = json.loads(result['messege']) if res.get('failed'): for hostname, info in res.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 if res.get('unreachable'): for hostname, info in res.get('unreachable').items(): if hostname in failed_asset.keys(): if info in failed_asset.get(hostname): failed_asset[hostname] += info else: failed_asset[hostname] = info if res.get('success'): for hostname, info in res.get('success').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) # 推送成功 回写push表 for asset in calc_assets: push_check = PermPush.objects.filter(role=role, asset=asset) if push_check: func = push_check.update else: def func(**kwargs): PermPush(**kwargs).save() if failed_asset.get(asset.networking.all()[0].ip_address): func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=False, result=failed_asset.get(asset.networking.all()[0].ip_address)) else: 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(success_asset.keys())) response['message'] = msg else: intersection = set(success_asset.keys())&set(failed_asset.keys()) if intersection: for item in intersection: success_asset.pop(item) error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % (role.name, ','.join(failed_asset.keys()), ','.join(success_asset.keys())) else: error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ] 进入系统用户详情,查看失败原因' % (role.name, ','.join(failed_asset.keys()), ','.join(success_asset.keys())) response['message'] = error except Exception as e: response['message'] = e return HttpResponse(json.dumps(response), content_type='application/json')
recycle_assets = [push.asset for push in role.perm_push.all() if push.success] logger.debug(u"delete role %s - delete_assets: %s" % (role.name, recycle_assets)) if recycle_assets: asset_proxys = gen_asset_proxy(recycle_assets) for key, value in asset_proxys.items(): proxy = Proxy.objects.filter(proxy_name=key)[0] recycle_resource = gen_resource(value) host_list = [asset.networking.all()[0].ip_address for asset in value] task = MyTask(recycle_resource, host_list) try: msg_del_user = task.del_user(role.name, proxy, request.user.username) msg_del_sudo = task.del_user_sudo(role.uuid_id, proxy, request.user.username) except Exception, e: logger.warning(u"Recycle Role failed: %s" % e) raise ServerError(u"回收已推送的系统用户失败: %s" % e) logger.info(u"删除用户 %s - execute delete user: %s" % (role.name, msg_del_user)) logger.info(u"删除用户 %s - execute delete sudo: %s" % (role.name, msg_del_sudo)) # TODO: 判断返回结果,处理异常 # 删除proxy上的role, proxy上的role删除成功后再删除magicstack上的role proxy_list = Proxy.objects.all() data = { 'name': role.name, } data = json.dumps(data) execute_thread_tasks(proxy_list, THREAD_NUMBERS,role_proxy_operator, request.user.username, 'PermRole', data, obj_uuid=role.uuid_id, action='delete') msg = u"删除系统用户[%s]成功" % role.name res['content'] = msg res['emer_status'] = msg role.delete() except ServerError, e: