130 lines
6.7 KiB
Python
130 lines
6.7 KiB
Python
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_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}"}
|
||
|