# -*-coding:utf-8-*- import requests import re import configparser import time import os from base_framework.platform_tools.Message_service.Feishu_api import FeiShuMessage from base_framework.public_tools.read_config import get_current_config,get_zhyy_config from base_framework.public_tools.sqlhelper import MySqLHelper from base_framework.base_config.current_pth import HERE from bs4 import BeautifulSoup from base_framework.public_tools.utils import Tools from lxml import etree from base_framework.public_tools import log obj_log = log.get_logger() obj_tool = Tools() class EurekaAPI: def __init__(self): self.business = get_current_config(section="run_evn_name", key="current_business") self.team = get_current_config(section="run_evn_name", key="current_team") self.evn = get_current_config(section="run_evn_name", key="current_evn") self.jira_id = get_current_config(section="run_jira_id", key="huohua-podenv") self.is_ip_from_ini = get_current_config(section="is_ip_from_ini", key="is_ip_from_ini") self.server_list = list() self.message = FeiShuMessage(team='AUTOMATION') if self.jira_id == '': self.jira_id = 'qa' self.server_to_domain = {"PEPPA-CORE-API": "https://core-api.qa.huohua.cn/"} self.sim_server_to_domain = {"PEPPA-TEACH-API": "https://teach-api.sim.huohua.cn/"} def __get_eureka_url_from_db(self, team): """ | 功能 | 从DB中获取服务对应的eureka_url,供get_container_ip_from_eureka函数使用 | """ sql_str = "select eureka_url as hh, eureka_url_hhi as hhi " \ "from sparkatp.swagger_info where team='{}';".format(team) res = MySqLHelper().select_one(sql=sql_str) return res[self.business] def __get_eureka_info_by_type(self, eureka_type): """ | 功能 | 根据eureka类型,返回对应的url和配置文件名 | """ if eureka_type.lower() == "hh": eureka_url = "http://eureka.{}.huohua.cn/".format(self.evn.lower()) eureka_file_name = "eureka_{}_huohua_cn.ini".format(self.evn.lower()) elif eureka_type.lower() == "vsl": eureka_url = "http://eureka.{}.visparklearning.com/".format(self.evn.lower()) eureka_file_name = "eureka_{}_visparklearning_com.ini".format(self.evn.lower()) elif eureka_type.lower() == "as": eureka_url = "http://eureka.{}.allschool.com/".format(self.evn.lower()) eureka_file_name = "eureka_{}_allschool_com.ini".format(self.evn.lower()) elif eureka_type.lower() == "ec": eureka_url = "http://eureka-core.{}.huohua.cn/".format(self.evn.lower()) eureka_file_name = "eureka_core_{}_huohua_cn.ini".format(self.evn.lower()) elif eureka_type.lower() == "xdu": eureka_url = "http://eureka.{}.xuedau.com/".format(self.evn.lower()) eureka_file_name = "eureka_{}_xuedau_com.ini".format(self.evn.lower()) else: raise Exception("eureka类型仅支持HH,VSL,AS,EC和XDU,但你的输入的是:{}".format(eureka_type)) return eureka_url, eureka_file_name def get_all_server_ip_from_eureka(self, eureka="HH"): """ | 功能说明: | 获取Eureka全部服务的IP,并写入对应文件中文件中 | | 输入参数: | eureka | 类型:HH | http://eureka.qa.huohua.cn/ | | | | 类型:VSL | http://eureka.qa.visparklearning.com/ | | | | 类型:AS | http://eureka.qa.allschool.com/ | | | | 类型:EC | http://eureka-core.qa.huohua.cn/ | | | | 类型:XDU | http://eureka.qa.xuedau.com/ | | 返回参数: | 无 | | | 作者信息: | 谯新久 | 2022.03.27 | """ eureka_url, eureka_file_name = self.__get_eureka_info_by_type(eureka_type=eureka) server_ip_path = os.path.join(HERE, eureka_file_name) temp_text = requests.get(url=eureka_url).content soup = BeautifulSoup(temp_text.decode('utf-8'), "html.parser") all_container_ip = soup.find_all(href=re.compile("actuator/info")) tree_dict = dict() for temp in all_container_ip: server = list(temp.parent.parent)[1].get_text() server_ip = list(temp) if server in tree_dict.keys(): tree_dict[server].extend(server_ip) else: tree_dict[server] = server_ip cof = configparser.ConfigParser() cof.read(server_ip_path, encoding='utf-8') eureka_section = self.business if eureka_section not in cof.sections(): cof.add_section(section=eureka_section) for svr_name in tree_dict: cof.set(section=eureka_section, option=svr_name, value=str(tree_dict[svr_name])) with open(server_ip_path, 'w') as fw: # 循环写入 cof.write(fw) time.sleep(2) # 等待5s,让ip写入到文件中去 def get_server_ip_from_config(self, server_name, eureka="HH"): """ | 功能说明: | 获取server_ip.ini文件中获取server_name对应的IP | | 输入参数: | server_name | 服务名 | | | eureka | 类型:HH | http://eureka.qa.huohua.cn/ | | | | 类型:VSL | http://eureka.qa.visparklearning.com/ | | | | 类型:AS | http://eureka.qa.allschool.com/ | | | | 类型:EC | http://eureka-core.qa.huohua.cn/ | | 返回参数: | string | 如:10.10.10.10:8080 | | 作者信息: | 谯新久 | 2022.03.27 | 特别说明: | 1 | 独立环境取startup.py启动时传入的值,没有对应的独立环境则取qa的ip返回 | | 2 | 当同一独立环境存在多个ip时,打印error日志后,返回第一个ip | """ eureka_url, eureka_file_name = self.__get_eureka_info_by_type(eureka_type=eureka) server_ip_path = os.path.join(HERE, eureka_file_name) ip_list = get_current_config(file_path=server_ip_path, section=self.business, key=server_name.lower()) if self.evn.lower() == "sim": ip_list = ip_list.replace("${server.port}", "8080") # 替换成8080端口 if self.jira_id in ip_list: jira = self.jira_id elif "sim" in ip_list: jira = "sim" elif "no" in ip_list: jira = "no" else: jira = "" elif self.jira_id in ip_list: jira = self.jira_id elif 'qa' in ip_list: jira = 'qa' elif 'groot' in ip_list: jira = 'groot' else: jira = 'qa' if ip_list != 'server not exist': if jira and jira not in ip_list: if server_name.lower() not in self.server_list: self.server_list.append(server_name.lower()) message = "{}在启动startup时发现服务{}在独立环境{}未部署成功,请确认。".format(self.team, server_name, jira) self.message.send_text(message) obj_ip = [] ip_str = ip_list.replace('[', '').replace(']', '').replace('\'', '').replace(' ', '') ip_list = ip_str.split(',') for ip in ip_list: if jira and jira in ip: # 找到对应独立环境的ip if ip.startswith('10.'): # 跳过非 obj_ip.append(ip) if self.evn.lower() == "sim": # sim环境只有一个ip时,直接返回次ip if not obj_ip and len(ip_list) == 1: ips = ip_list[0].split(":") return "{}:{}".format(ips[0], ips[1]) if self.evn.lower() != "sim" and len(obj_ip) > 1: # sim环境不判断是否有多个部署 obj_log.error("eureka中含有{}个{}的{}环境,请检查.........".format(len(obj_ip), server_name, jira)) elif len(obj_ip) == 0: obj_log.error("eureka中未找到{}的{}相关的ip信息,请检查.........".format(server_name, jira)) return "server not exist" # return obj_ip[0].rstrip("{}".format(jira))[:-1] return obj_ip[0].split("{}".format(jira))[0].rstrip(":") else: obj_log.error("eureka中未找到{}的{}相关的ip信息,请检查.........".format(server_name, jira)) return "server not exist" def get_server_url_from_config(self, server_name, eureka="HH", is_domain=True): """ | 功能说明: | 从对应文件中获取server_name对应的IP,组装成url后返回 | | 输入参数: | server_name | 服务名 | | | eureka | 类型:HH | http://eureka.qa.huohua.cn/ | | | | 类型:VSL | http://eureka.qa.visparklearning.com/ | | | | 类型:AS | http://eureka.qa.allschool.com/ | | | | 类型:EC | http://eureka-core.qa.huohua.cn/ | | | | 类型:XDU | http://eureka.qa.xuedau.com/ | | | is_domain | 是否域名,True域名,False IP | | 返回参数: | string | 如:http://10.10.10.10:8080/ | | 作者信息: | 谯新久 | 2022.03.27 | 特别说明: | 1 | 独立环境取startup.py启动时传入的值,没有对应的独立环境则取qa的ip返回 | | 2 | 当同一独立环境存在多个ip时,打印error日志后,返回第一个ip | """ if is_domain: if self.evn == "SIM": if server_name.upper() in self.sim_server_to_domain.keys(): return self.sim_server_to_domain[server_name.upper()] return "https://swagger.sim.huohua.cn/{}/".format(server_name.lower()) if server_name.upper() in self.server_to_domain.keys(): return self.server_to_domain[server_name.upper()] return "https://swagger.qa.huohua.cn/{}/".format(server_name.lower()) else: # eureka_url, _ = self.__get_eureka_info_by_type(eureka_type=eureka) # ip_res = obj_tool.get_container_ip_from_eureka(server_name=server_name, jira_id_dev=self.jira_id, # eureka_url=eureka_url) # if ip_res: # ip_info = ip_res["container_ip"] # url_info = "http://" + ip_info + ":8080/" # return url_info # # if self.is_ip_from_ini == "true": ip_info = self.get_server_ip_from_config(server_name=server_name.lower(), eureka=eureka) if ip_info != 'server not exist': url_info = "http://" + ip_info + "/" return url_info else: raise Exception("eureka中未找到{}的{}相关的ip信息,请检查.........".format(server_name, self.jira_id)) def get_url_from_config(self, is_domain=True): """ | 功能说明: | 从对应文件中获取对应环境的域名,组装成url后返回 | | 输入参数: | 环境 | 服务名 | | | is_domain | 是否域名,True域名,False IP | | 返回参数: | string | 如:http://10.10.10.10:8080/ | | 作者信息: | 谯新久 | 2026.01.15 | """ if is_domain: env = self.evn.upper() team = self.team.lower() domain_url = get_zhyy_config(section=env, key=team) return domain_url else: #todo 暂无ip return # # if self.is_ip_from_ini == "true": # ip_info = self.get_server_ip_from_config(server_name=server_name.lower(), eureka=eureka) # if ip_info != 'server not exist': # url_info = "http://" + ip_info + "/" # return url_info # else: # raise Exception("eureka中未找到{}的{}相关的ip信息,请检查.........".format(server_name, self.jira_id)) if __name__ == '__main__': er = EurekaAPI() # er.get_all_server_ip_from_eureka # er.get_all_server_ip_from_eureka(eureka="VSL") res = er.get_server_url_from_config(server_name='peppa-scm-server', is_domain=False) print(res) # res = er.get_server_url_from_config(server_name='sparkedu-api', eureka="VSL") # print(res)