import requests,json,re,traceback from config import consul_token,consul_url from units.config_log import * headers = {'X-Consul-Token': consul_token} def get_consul_ver(): url = f'{consul_url}/operator/autopilot/state' response = requests.get(url, headers=headers, timeout=2) if response.status_code == 404: url = f'{consul_url}/operator/autopilot/health' response = requests.get(url, headers=headers, timeout=2) response.encoding='utf-8' if response.status_code == 200: logger.info(f'【consul】请求成功, 认证成功: {consul_url} ') return True elif response.status_code == 403: logger.error(f'【consul】连接正常: {consul_url}【认证失败】请检查consul token!') return False elif response.status_code == 404: logger.error(f'【consul】连接异常 {response.status_code}: {consul_url}, 您的consul版本可能过低!') return False else: logger.error(f'【consul】连接失败 {response.status_code}: {consul_url}, 请检查consul状态以及网络是否正常!') return False def get_hosts(): url = f'{consul_url}/agent/host' response = requests.get(url, headers=headers) if response.status_code == 200: info = response.json() pmem = round(info["Memory"]["usedPercent"]) pdisk = round(info["Disk"]["usedPercent"]) host = {'hostname':info["Host"]["hostname"],'uptime':f'{round(info["Host"]["uptime"]/3600/24)}天', 'os':f'{info["Host"]["platform"]} {info["Host"]["platformVersion"]}','kernel':info["Host"]["kernelVersion"]} cpu = {'cores':f'{len(info["CPU"])}核','vendorId':info["CPU"][0]["vendorId"],'modelName':info["CPU"][0]["modelName"]} memory = {'total':f'{round(info["Memory"]["total"]/1024**3)}GB','available':f'{round(info["Memory"]["available"]/1024**3)}GB', 'used':f'{round(info["Memory"]["used"]/1024**3)}GB','usedPercent':f'{pmem}%'} disk = {'path':info["Disk"]["path"],'fstype':info["Disk"]["fstype"],'total':f'{round(info["Disk"]["total"]/1024**3)}GB', 'free':f'{round(info["Disk"]["free"]/1024**3)}GB','used':f'{round(info["Disk"]["used"]/1024**3)}GB','usedPercent':f'{pdisk}%'} return {'code': 20000,'host':host,'cpu':cpu,'memory':memory,'disk':disk, 'pmem':pmem, 'pdisk':pdisk} else: logger.error(f"{response.status_code}:{response.text}") return {'code': 50000, 'data': f'{response.status_code}:{response.text}'} def get_services(): url = f'{consul_url}/internal/ui/services' response = requests.get(url, headers=headers) if response.status_code == 200: info = response.json() services_list = [{'Name':i['Name'],'Datacenter':i.get('Datacenter','Null'),'InstanceCount':i['InstanceCount'],'ChecksCritical':i['ChecksCritical'],'ChecksPassing':i['ChecksPassing'],'Tags':i['Tags'],'Nodes':list(set(i['Nodes']))} for i in info if i['Name'] != 'consul'] return {'code': 20000,'services':services_list} else: return {'code': 50000, 'data': f'{response.status_code}:{response.text}'} def get_services_nameonly(): url = f'{consul_url}/catalog/services' response = requests.get(url, headers=headers) if response.status_code == 200: info = response.json() info.pop('consul') return {'code': 20000,'services_name':list(info.keys())} else: logger.error(f"{response.status_code}:{response.text}") return {'code': 50000, 'data': f'{response.status_code}:{response.text}'} def get_instances(service_name): url = f'{consul_url}/health/service/{service_name}' response = requests.get(url, headers=headers) if response.status_code == 200: info = response.json() instances_list = [] for i in info: instance_dict = {} instance_dict['ID'] = i['Service']['ID'] instance_dict['name'] = i['Service']['Service'] instance_dict['tags'] = '无' if i['Service']['Tags'] == [] else i['Service']['Tags'] instance_dict['address'] = i['Service'].get('Address') instance_dict['port'] = i['Service'].get('Port') if i['Service']['Meta'] == {} or i['Service']['Meta'] is None: instance_dict['meta'] = '无' else: instance_dict['meta'] = [i['Service']['Meta']] instance_dict['meta_label'] = [{'prop': x, 'label': x} for x in i['Service']['Meta'].keys()] if len(i['Checks']) ==2: instance_dict['status'] = i['Checks'][1]['Status'] instance_dict['output'] = i['Checks'][1]['Output'] else: instance_dict['status'] = '无' instance_dict['output'] = '无' instances_list.append(instance_dict) return {'code': 20000,'instances':instances_list} else: logger.error(f"{response.status_code}:{response.text}") return {'code': 50000, 'data': f'{response.status_code}:{response.text}'} def del_instance(sid): reg = requests.put(f'{consul_url}/agent/service/deregister/{sid}', headers=headers) if reg.status_code == 200: logger.debug(f"【{sid}】删除成功!") return {"code": 20000, "data": f"【{sid}】删除成功!"} else: logger.error(f"{reg.status_code}【{sid}】{reg.text}") return {"code": 50000, "data": f"{reg.status_code}【{sid}】{reg.text}"} def add_instance(instance_dict): sid = instance_dict['ID'].strip() sid = re.sub('[[ \]`~!\\\#$^&*=|"{}\':;?\t\n]','_',sid) if '//' in sid or sid.startswith('/') or sid.endswith('/'): return {"code": 50000, "data": f"服务ID【{sid}】首尾不能包含'/',并且不能包含两个连续的'/'"} isMeta = instance_dict['metaInfo']['isMeta'] isCheck = instance_dict['checkInfo']['isCheck'] address = instance_dict['address'] port = None if (instance_dict['port'] == '' or instance_dict['port'] is None) else int(instance_dict['port']) instance_dict['port'] = port if isMeta: try: metaJson = json.loads(instance_dict['metaInfo']['metaJson']) instance_dict['meta'] = metaJson except Exception as e: logger.error(f'{e}\n{traceback.format_exc()}') return {"code": 50000, "data": "Meta必须JSON字符串格式!"} if isCheck: ctype = instance_dict['checkInfo']['ctype'] interval = instance_dict['checkInfo']['interval'] timeout = instance_dict['checkInfo']['timeout'] if instance_dict['checkInfo']['isAddress'] == 'true': if port is not None and address != '' and ctype != 'HTTP': checkaddress = f'{address}:{port}' elif port is not None and address != '' and ctype == 'HTTP': checkaddress = f'http://{address}:{port}' else: return {"code": 50000, "data": "健康检查地址使用与实例IP端口一致时,地址/端口不可为空!"} else: checkaddress = instance_dict['checkInfo']['caddress'] if checkaddress == '': return {"code": 50000, "data": "自定义健康检查,地址信息不可为空!"} check = {ctype: checkaddress,"Interval": interval,"Timeout": timeout} instance_dict['check'] = check del instance_dict['metaInfo'] del instance_dict['checkInfo'] logger.info(f'{instance_dict}') reg = requests.put(f'{consul_url}/agent/service/register', headers=headers, data=json.dumps(instance_dict)) if reg.status_code == 200: return {"code": 20000, "data": f"【{sid}】增加成功!"} else: logger.error(f"{reg.status_code}【{sid}】{reg.text}") return {"code": 50000, "data": f"{reg.status_code}【{sid}】{reg.text}"}