def nginx_upstream(request): reg1 = re.compile(r'\nupstream[^\}]+}') reg2 = re.compile(r'\nupstream[^\{]+') reg3 = re.compile(r'\#* *server \d[^;]+;') reg4 = re.compile(r'\#+ *') upstreamlist = [] try: if request.method == 'GET': minionid = request.GET.get('minionid') nginxip = request.GET.get('nginxip') path = request.GET.get('path') with requests.Session() as s: saltapi = SaltAPI(session=s) if saltapi.get_token() is False: logger.error( 'nginx_upstream页get操作获取SaltAPI调用get_token请求出错') return render(request, 'nginx/nginx_upstream.html') else: response_data = saltapi.cmd_run_api(tgt=minionid, arg='cat %s' % path) if response_data is False: logger.error( '获取upstream列表失败可能代入的参数有问题,SaltAPI调用cmd_run_api请求出错' ) return render(request, 'nginx/nginx_upstream.html') # 判断upstream_data如果返回值如果为[{}]表明没有这个minionid elif response_data['return'] != [{}]: data_source = response_data['return'][0][minionid] data_list = re.findall(reg1, data_source) for i in data_list: # 获取upstream name b2 = re.search(reg2, i) # 获取upstream server列表 b3 = re.findall(reg3, i) # 用空格切割字符串取第二个就是servername了 namekey = b2.group().split(' ')[1] # 下面这个如果直接赋值b3会有一些问题,就是出现'## server'这样的也会被前端输出,所以用了 # 正则把这种出现'### '是全部替换成#这样不仅显示正常,在下面post中获取的前端upstream_server也会正确,很重要 upstreamlist.append([ namekey, [re.sub(reg4, '#', x.strip()) for x in b3] ]) return render( request, 'nginx/nginx_upstream.html', { 'upstreamlist': upstreamlist, 'minionid': minionid, 'nginxip': nginxip, 'path': path }) else: logger.error('获取upstream列表失败,请确认minion是否存在。。') return render(request, 'nginx/nginx_upstream.html') # 切换里面server的up/down状态,其实就是注释加#和不注释而已 else: upstream_name = request.POST.get('upstream_name') upstream_server = request.POST.get('upstream_server') upstream_status = request.POST.get('upstream_status') minionid = request.POST.get('minionid') path = request.POST.get('path') with requests.Session() as s: saltapi = SaltAPI(session=s) if saltapi.get_token() is False: logger.error( 'nginx_upstream页状态变更操作获取SaltAPI调用get_token请求出错') return JsonResponse({'result': '失败,后台问题', 'status': False}) else: if upstream_status == 'down': arg = "sed -i '/^upstream *%s/,/^}$/{s/%s/#%s/g}' %s&&free -m" % ( upstream_name, upstream_server, upstream_server, path) else: arg = "sed -i '/^upstream *%s/,/^}$/{s/#\+ *%s/%s/g}' %s&&free -m" % ( upstream_name, upstream_server, upstream_server, path) response_data = saltapi.cmd_run_api(tgt=minionid, arg=arg) if response_data is False: logger.error( 'nginx_upstream页状态变更SaltAPI调用cmd_run_api请求出错') return JsonResponse({ 'result': '失败,后台问题', 'status': False }) # 返回值如果为[{}]表明没有这个minionid elif response_data['return'] == [{}]: logger.error( 'nginx_upstream页状态变更SaltAPI调用cmd_run_api获取到空值了') return JsonResponse({ 'result': '失败,后台问题', 'status': False }) else: return JsonResponse({'result': '成功', 'status': True}) except Exception as e: logger.error('获取upstream列表失败' + str(e)) return render(request, 'nginx/nginx_upstream.html')
def old2_minion_status(): # 用values_list配合flat=True得到minion_id的列表,用values_list获取的不是列表是QuerySet对象 # 如果要执行append或者remove等list操作无法执行 minion_list = MinionList.objects.values_list('minion_id', flat=True) id_list = [] print('开始更新Minion列表' + time.strftime('%Y年%m月%d日 %X')) with requests.Session() as s: saltapi = SaltAPI(session=s) if saltapi.get_token() is False: logger.error('minion_status定时操作获取SaltAPI调用get_token请求出错') print('minion_status定时操作获取SaltAPI调用get_token请求出错') return False else: # salt检测minion最快的方法,不访问minion而是直接通过和端口4505保持连接的ip来检测,和我旧版手动写功能一样,官方也出了 # 目前这个方法有个不算BUG的BUG就是环境必须是内网,如果出现用nat端口转发则因为这个命令本身获取是master的端口连接装态通过 # nat过来的连接ip都会是一个nat出口ip,导致判断错误,所以如果确认都是内网环境才可以使用 online_data = saltapi.saltrun_manage_alive_api( arg='show_ipv4=True') if online_data is False: print('saltrun_manage_alive_api调用API失败了') return False elif online_data['return'] == [[]]: print('没有在线的minion,搞笑') else: try: id_list.extend([key for key in online_data['return'][0]]) grains_data = saltapi.grains_itmes_api(tgt=id_list, tgt_type='list') # 这里获取了所有minion的grains内容,如果以后表字段有增加就从这里取方便 for key, value in grains_data['return'][0].items(): minion_id = key ip = online_data['return'][0][key] os = value['os'] + value['osrelease'] saltversion = value['saltversion'] sn = value['serialnumber'] cpu_num = value['num_cpus'] cpu_model = value['cpu_model'] sys = value['kernel'] kernel = value['kernelrelease'] productname = value['productname'] ipv4_addr = value['ip4_interfaces'] mac_addr = value['hwaddr_interfaces'] localhost = value['localhost'] mem_total = value['mem_total'] updated_values = { 'minion_id': minion_id, 'minionstatus': '在线', 'ip': ip, 'sn': sn, 'cpu_num': cpu_num, 'cpu_model': cpu_model, 'sys': sys, 'kernel': kernel, 'productname': productname, 'ipv4_addr': ipv4_addr, 'mac_addr': mac_addr, 'localhost': localhost, 'mem_total': mem_total, 'minionversion': saltversion, 'systemissue': os, 'updatetime': time.strftime('%Y年%m月%d日 %X') } MinionList.objects.update_or_create( minion_id=key, defaults=updated_values) except Exception as e: print( 'minion列表更新在线数据出错1,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False offline_data = saltapi.saltrun_manage_notalive_api() if offline_data is False: print('saltrun_manage_notalive_api调用API失败了') return False elif offline_data['return'] == [[]]: print('恭喜有没离线的minion') else: try: # 获取不在线结果的结构是这样的:{'return': [['10.10.10.100', '10.10.10.116']]} for key in offline_data['return'][0]: id_list.append(key) updated_values = { 'minion_id': key, 'minionstatus': '离线', 'updatetime': time.strftime('%Y年%m月%d日 %X') } MinionList.objects.update_or_create( minion_id=key, defaults=updated_values) except Exception as e: print( 'minion列表更新离线数据出错2,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False # 清理表中多出来的条目 try: for i in minion_list: if i not in id_list: MinionList.objects.filter(minion_id=i).delete() print('minion列表更新完成' + time.strftime('%Y年%m月%d日 %X')) return True except Exception as e: print('minion列表更新出错,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False
def minion_status(): # 用values_list配合flat=True得到minion_id的列表,用values_list获取的不是列表是QuerySet对象 # 如果要执行append或者remove等list操作无法执行 minion_list = MinionList.objects.values_list('minion_id', flat=True) id_list = [] print('开始更新Minion列表' + time.strftime('%Y年%m月%d日 %X')) with requests.Session() as s: saltapi = SaltAPI(session=s) if saltapi.get_token() is False: logger.error('minion_status定时操作获取SaltAPI调用get_token请求出错') print('minion_status定时操作获取SaltAPI调用get_token请求出错') return False else: # salt检测minion最准的方法salt-run manage.status minion_data = saltapi.saltrun_manage_status_api() if minion_data is False: print('saltrun_manage_status_api调用API失败了') return False else: try: id_list.extend(minion_data['return'][0]['up']) grains_data = saltapi.grains_itmes_api(tgt=id_list, tgt_type='list') # 这里获取了所有minion的grains内容,如果以后表字段有增加就从这里取方便 for key, value in grains_data['return'][0].items(): minion_id = key try: value['ipv4'].remove('127.0.0.1') except Exception as e: pass try: # 下面这段代码之前都是直接用cpu_model = value['cpu_model'] 后面发现centos6和7有的有这个key有的没有导致会 # 报错,所以改成用get来获取key安全哈哈 ip = value.get('ipv4') os = value.get('os') + value.get('osrelease') saltversion = value.get('saltversion') sn = value.get('serialnumber') cpu_num = value.get('num_cpus') cpu_model = value.get('cpu_model') sys = value.get('kernel') kernel = value.get('kernelrelease') productname = value.get('productname') ipv4_addr = value.get('ip4_interfaces') mac_addr = value.get('hwaddr_interfaces') localhost = value.get('localhost') mem_total = value.get('mem_total') except Exception as e: # 有出现过某个minion的依赖文件被删除了但是minion进程还在,导致grains.items没有结果返回 # 这样就会出现vlaue不是一个字典而是是一个str正常value内容是{'ipv4':'xxxxx'}异常时候会是'grains.items is false' # 具体是什么str没记住哈哈,不过由于不少字典而又用了get来获取字典值所以会触发try的错误,也就有了下面的操作 updated_values = { 'minion_id': key, 'minion_status': '异常', 'update_time': time.strftime('%Y年%m月%d日 %X') } MinionList.objects.update_or_create( minion_id=key, defaults=updated_values) else: updated_values = { 'minion_id': minion_id, 'minion_status': '在线', 'ip': ip, 'sn': sn, 'cpu_num': cpu_num, 'cpu_model': cpu_model, 'sys': sys, 'kernel': kernel, 'product_name': productname, 'ipv4_address': ipv4_addr, 'mac_address': mac_addr, 'localhost': localhost, 'mem_total': mem_total, 'minion_version': saltversion, 'system_issue': os, 'update_time': time.strftime('%Y年%m月%d日 %X') } MinionList.objects.update_or_create( minion_id=key, defaults=updated_values) except Exception as e: print( 'minion列表更新在线数据出错1,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False try: # 更新离线minion状态 for key in minion_data['return'][0]['down']: id_list.append(key) updated_values = { 'minion_id': key, 'minion_status': '离线', 'update_time': time.strftime('%Y年%m月%d日 %X') } MinionList.objects.update_or_create( minion_id=key, defaults=updated_values) except Exception as e: print( 'minion列表更新离线数据出错2,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False # 清理表中多出来的条目 try: for i in minion_list: if i not in id_list: MinionList.objects.filter(minion_id=i).delete() # 下面这些本来是用来操作清理minion表后一些关联了minion的业务表也删除,但是后面想想我不动声响的后台去删除这些 # 表中的数据,对于使用人来说是很坑爹的事情,等下人家都不知道怎么minion就消失了,然后可能还会忘了到底原来是关联 # 那一个minion_id的,所以最后想了想还是不删除;业务逻辑中写判断minion是否存在,这样还有一个问题就是如果minion # 清理后再重新添加回来,假设加回来的是另一台服务器那会造成业务系统之前绑定了这个minion的在操作的时候会操作错误 # 因为minion实际的后端服务器换了一台,所以要在规范上面来避免这问题,尽量小心删除salt-key操作,检查是否有关联 # 业务,或者后期看下需不需要下面的删除操作改成类似添加备注说明下被删除了 # # 对AppRelease中的minion_id做删除操作,因为这个表关联了minion表,不过我没用外键,所以要手动来 # # 下面是用正则匹配minion_id只有一个或者多个时候在前面在中间在最后的情况 # app_data_list = AppRelease.objects.filter( # minion_id__regex=r'^%s$|^%s,|,%s$|,%s,' % (i, i, i, i)) # for app_data in app_data_list: # app_name = app_data.app_name # minion_id = app_data.minion_id # minion_id = minion_id.split(',') # minion_id.remove(i) # minion_id = ','.join(minion_id) # AppRelease.objects.filter(app_name=app_name).update(minion_id=minion_id) print('minion列表更新完成' + time.strftime('%Y年%m月%d日 %X')) return True except Exception as e: logger.error('minion列表更新出错,请检查' + time.strftime('%Y年%m月%d日 %X') + str(e)) print('minion列表更新出错,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False
def saltkey_list(): print('开始更新SaltKeyList表' + time.strftime('%Y年%m月%d日 %X')) salt_list = SaltKeyList.objects.values_list('minion_id', 'certification_status') minion_list = [] with requests.Session() as s: saltapi = SaltAPI(session=s) if saltapi.get_token() is False: logger.error('saltkey_list定时操作获取SaltAPI调用get_token请求出错') print('saltkey_list定时操作获取SaltAPI调用get_token请求出错') return False else: response_data = saltapi.saltkey_listall_api() try: data_source = response_data['return'][0]['data']['return'] minions_pre = data_source['minions_pre'] minions_denied = data_source['minions_denied'] minions = data_source['minions'] minions_rejected = data_source['minions_rejected'] if minions_pre: for i in minions_pre: minion_list.append((i, 'unaccepted')) updated_values = { 'minion_id': i, 'certification_status': 'unaccepted', 'update_time': time.strftime('%Y年%m月%d日 %X') } SaltKeyList.objects.update_or_create( minion_id=i, certification_status='unaccepted', defaults=updated_values) if minions_denied: for i in minions_denied: minion_list.append((i, 'denied')) updated_values = { 'minion_id': i, 'certification_status': 'denied', 'update_time': time.strftime('%Y年%m月%d日 %X') } SaltKeyList.objects.update_or_create( minion_id=i, certification_status='denied', defaults=updated_values) if minions: for i in minions: minion_list.append((i, 'accepted')) updated_values = { 'minion_id': i, 'certification_status': 'accepted', 'update_time': time.strftime('%Y年%m月%d日 %X') } SaltKeyList.objects.update_or_create( minion_id=i, certification_status='accepted', defaults=updated_values) if minions_rejected: for i in minions_rejected: minion_list.append((i, 'rejected')) updated_values = { 'minion_id': i, 'certification_status': 'rejected', 'update_time': time.strftime('%Y年%m月%d日 %X') } SaltKeyList.objects.update_or_create( minion_id=i, certification_status='rejected', defaults=updated_values) # 删除原表中不在本次查询结果里的记录,因为如果你删除了一个minion那么查询结果就没有这个minion了所以要从表中删除 for i in salt_list: if i not in minion_list: SaltKeyList.objects.filter( minion_id=i[0], certification_status=i[1]).delete() print('saltkey_list表更新完成' + time.strftime('%Y年%m月%d日 %X')) return True except Exception as e: logger.error('saltkey_list在执行数据库操作时候出错了:' + str(e)) print('saltkey_list表更新出错,请检查' + time.strftime('%Y年%m月%d日 %X'), e) return False