取消 ReferenceField 字段,改用字符串字段存储对象id,手动关联,接口同步修改
This commit is contained in:
parent
7cb3848751
commit
8d54f9e8fd
|
@ -13,3 +13,11 @@ def is_ipaddr(ip):
|
||||||
ipaddress.ip_address(ip)
|
ipaddress.ip_address(ip)
|
||||||
except:
|
except:
|
||||||
raise mongo.ValidationError('The value must be a ip address')
|
raise mongo.ValidationError('The value must be a ip address')
|
||||||
|
|
||||||
|
|
||||||
|
def is_hex_string(string: str):
|
||||||
|
"""校验 hex 字符串(十六进制)"""
|
||||||
|
try:
|
||||||
|
int(string, 16)
|
||||||
|
except:
|
||||||
|
raise mongo.ValidationError('The value must be a hex string')
|
||||||
|
|
|
@ -83,6 +83,8 @@ AgentServerFields = {
|
||||||
"is_cross": fields.Boolean,
|
"is_cross": fields.Boolean,
|
||||||
# "channel_id": fields.String,
|
# "channel_id": fields.String,
|
||||||
"project": fields.String,
|
"project": fields.String,
|
||||||
|
"project_name": fields.String,
|
||||||
|
"project_fork": fields.String,
|
||||||
"public_ip": fields.String,
|
"public_ip": fields.String,
|
||||||
"private_ip": fields.String,
|
"private_ip": fields.String,
|
||||||
# "host_id": fields.String,
|
# "host_id": fields.String,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import mongoengine as mongo
|
||||||
|
|
||||||
from settings import common
|
from settings import common
|
||||||
from common.document import DocumentBase
|
from common.document import DocumentBase
|
||||||
from common.validator import isalnum
|
from common.validator import isalnum, is_hex_string
|
||||||
|
|
||||||
from asset.models import Host
|
from asset.models import Host
|
||||||
|
|
||||||
|
@ -44,9 +44,9 @@ class Version(mongo.EmbeddedDocument):
|
||||||
class Channel(DocumentBase):
|
class Channel(DocumentBase):
|
||||||
"""渠道"""
|
"""渠道"""
|
||||||
# spid项目内唯一
|
# spid项目内唯一
|
||||||
project = mongo.ReferenceField(Project, reverse_delete_rule=mongo.NULLIFY)
|
project_id = mongo.StringField(max_length=128, required=True, validation=is_hex_string)
|
||||||
name = mongo.StringField(max_length=32, default="")
|
name = mongo.StringField(max_length=32, default="")
|
||||||
spid = mongo.StringField(max_length=3, min_length=3, required=True, unique_with="project", validation=isalnum)
|
spid = mongo.StringField(max_length=3, min_length=3, required=True, unique_with="project_id", validation=isalnum)
|
||||||
version = mongo.EmbeddedDocumentField(Version) # 缺失时获取对象的此字段为 None
|
version = mongo.EmbeddedDocumentField(Version) # 缺失时获取对象的此字段为 None
|
||||||
|
|
||||||
# 项目的代码仓库地址
|
# 项目的代码仓库地址
|
||||||
|
@ -64,6 +64,20 @@ class Channel(DocumentBase):
|
||||||
"""渠道 spid 在 CROSS_SPID_SET,表示跨服"""
|
"""渠道 spid 在 CROSS_SPID_SET,表示跨服"""
|
||||||
return self.spid in common.CROSS_SPID_SET
|
return self.spid in common.CROSS_SPID_SET
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project(self):
|
||||||
|
if self.project_id:
|
||||||
|
return Project.objects(id=self.project_id).first()
|
||||||
|
return None
|
||||||
|
|
||||||
|
@project.setter
|
||||||
|
def project(self, val):
|
||||||
|
if isinstance(val, str):
|
||||||
|
assert Project.objects(id=val).first(), f"对象不存在,id={val}"
|
||||||
|
self.project_id = val
|
||||||
|
if isinstance(val, Project):
|
||||||
|
self.project_id = str(val.id)
|
||||||
|
|
||||||
|
|
||||||
class Server(DocumentBase):
|
class Server(DocumentBase):
|
||||||
"""服务"""
|
"""服务"""
|
||||||
|
@ -77,12 +91,13 @@ class Server(DocumentBase):
|
||||||
"error": "异常"
|
"error": "异常"
|
||||||
}
|
}
|
||||||
|
|
||||||
num = mongo.IntField(required=True, unique_with="channel")
|
num = mongo.IntField(required=True, unique_with="channel_id")
|
||||||
channel = mongo.ReferenceField(Channel)
|
# 关联channel表,保存是一个channel._id的hex字符串
|
||||||
|
channel_id = mongo.StringField(max_length=128, required=True, validation=is_hex_string)
|
||||||
status = mongo.StringField(max_length=12, choices=STATUS.keys(), required=True, default="running")
|
status = mongo.StringField(max_length=12, choices=STATUS.keys(), required=True, default="running")
|
||||||
|
|
||||||
# 机器字段,TODO 先允许为空
|
# 机器字段,TODO 先允许为空
|
||||||
host = mongo.ReferenceField(Host, null=True)
|
host_id = mongo.StringField(max_length=128, null=True, validation=is_hex_string)
|
||||||
domain = mongo.StringField(max_length=128, required=False, default="")
|
domain = mongo.StringField(max_length=128, required=False, default="")
|
||||||
port = mongo.IntField()
|
port = mongo.IntField()
|
||||||
version = mongo.EmbeddedDocumentField(Version)
|
version = mongo.EmbeddedDocumentField(Version)
|
||||||
|
@ -106,17 +121,38 @@ class Server(DocumentBase):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def channel_id(self):
|
def channel(self):
|
||||||
if self.channel:
|
"""非强关联,方便取出channel对象"""
|
||||||
return self.channel.id
|
if self.channel_id:
|
||||||
|
return Channel.objects(id=self.channel_id).first()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@channel.setter
|
||||||
|
def channel(self, val):
|
||||||
|
if isinstance(val, str):
|
||||||
|
assert Channel.objects(id=val).first(), f"对象不存在,id={val}"
|
||||||
|
self.channel_id = val
|
||||||
|
if isinstance(val, Channel):
|
||||||
|
self.channel_id = str(val.id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project(self):
|
def project(self):
|
||||||
if self.channel:
|
if self.channel and self.channel.project:
|
||||||
return self.channel.project.fullname
|
return self.channel.project.fullname
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project_name(self):
|
||||||
|
if self.channel and self.channel.project:
|
||||||
|
return self.channel.project.name
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project_fork(self):
|
||||||
|
if self.channel and self.channel.project:
|
||||||
|
return self.channel.project.fork
|
||||||
|
return ""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_ip(self):
|
def public_ip(self):
|
||||||
if self.host:
|
if self.host:
|
||||||
|
@ -130,11 +166,20 @@ class Server(DocumentBase):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def host_id(self):
|
def host(self):
|
||||||
if self.host:
|
"""非强关联,为了取出host对象"""
|
||||||
return self.host.id
|
if self.host_id:
|
||||||
|
return Host.objects(id=self.host_id).first()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@host.setter
|
||||||
|
def host(self, val):
|
||||||
|
if isinstance(val, str):
|
||||||
|
assert Host.objects(id=val).first(), f"对象不存在,id={val}"
|
||||||
|
self.host_id = val
|
||||||
|
if isinstance(val, Host):
|
||||||
|
self.host_id = str(val.id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_cross(self):
|
def is_cross(self):
|
||||||
if self.channel:
|
if self.channel:
|
||||||
|
|
|
@ -65,7 +65,7 @@ class ServerSyncView(CreateMixin):
|
||||||
|
|
||||||
if count != len(data):
|
if count != len(data):
|
||||||
return make_response(400, 1001, "quantity mismatch")
|
return make_response(400, 1001, "quantity mismatch")
|
||||||
|
project_id = str(self.project.id)
|
||||||
hosts = {}
|
hosts = {}
|
||||||
channels = {}
|
channels = {}
|
||||||
errors = []
|
errors = []
|
||||||
|
@ -89,17 +89,17 @@ class ServerSyncView(CreateMixin):
|
||||||
if not created and proj not in hostObj.tags:
|
if not created and proj not in hostObj.tags:
|
||||||
hostObj.tags.append(proj)
|
hostObj.tags.append(proj)
|
||||||
hostObj.save()
|
hostObj.save()
|
||||||
host = hostObj.id
|
host = str(hostObj.id)
|
||||||
hosts[ip] = hostObj.id
|
hosts[ip] = host
|
||||||
if not channel:
|
if not channel:
|
||||||
channelObj, _ = Channel.get_or_create(
|
channelObj, _ = Channel.get_or_create(
|
||||||
project=self.project, spid=spid, defaults=dict(project=self.project, spid=spid))
|
project_id=project_id, spid=spid, defaults=dict(project_id=project_id, spid=spid))
|
||||||
channel = channelObj.id
|
channel = str(channelObj.id)
|
||||||
channels[spid] = channelObj.id
|
channels[spid] = channel
|
||||||
|
|
||||||
# 更新、创建的参数
|
# 更新、创建的参数
|
||||||
defaults = dict(num=num, channel=channel, host=host, version=version, port=port, status=status)
|
defaults = dict(num=num, channel_id=channel, host_id=host, version=version, port=port, status=status)
|
||||||
obj, created = Server.update_or_create(defaults=defaults, num=num, channel=channel)
|
obj, created = Server.update_or_create(defaults=defaults, num=num, channel_id=channel)
|
||||||
if created: # 创建
|
if created: # 创建
|
||||||
app.logger.debug(f"创建 {spid}_{num} 区服信息成功")
|
app.logger.debug(f"创建 {spid}_{num} 区服信息成功")
|
||||||
continue
|
continue
|
||||||
|
@ -119,6 +119,8 @@ class ServerSyncView(CreateMixin):
|
||||||
class AgentInfo(RetrieveMixin):
|
class AgentInfo(RetrieveMixin):
|
||||||
"""返回对应机器的所有信息:项目、渠道、区服内容"""
|
"""返回对应机器的所有信息:项目、渠道、区服内容"""
|
||||||
fields = {
|
fields = {
|
||||||
|
# marshal schedule dict
|
||||||
|
"schedule": F.Raw,
|
||||||
"host": F.Nested(HostFields),
|
"host": F.Nested(HostFields),
|
||||||
"project": F.List(F.Nested(fields.ProjectFields)),
|
"project": F.List(F.Nested(fields.ProjectFields)),
|
||||||
"channel": F.List(F.Nested(fields.ChannelFields)),
|
"channel": F.List(F.Nested(fields.ChannelFields)),
|
||||||
|
@ -133,11 +135,19 @@ class AgentInfo(RetrieveMixin):
|
||||||
# 找到机器,不存在就404
|
# 找到机器,不存在就404
|
||||||
host = Host.objects(minion_id=agent_id).first_or_404(message="resource not found")
|
host = Host.objects(minion_id=agent_id).first_or_404(message="resource not found")
|
||||||
# 根据机器找区服集合,返回
|
# 根据机器找区服集合,返回
|
||||||
servers = Server.objects(host=host).all()
|
servers = Server.objects(host_id=str(host.id)).all()
|
||||||
channels = servers.values_list("channel").distinct("channel")
|
channels = Channel.objects(id__in=servers.values_list("channel_id").distinct("channel_id"))
|
||||||
projects = [channel.project for channel in channels]
|
projects = {channel.project for channel in channels}
|
||||||
# 填充数据
|
# 填充数据
|
||||||
data = {
|
data = {
|
||||||
|
# TODO schedule 这里的内容可以动态配置,为 minion 增加计划任务
|
||||||
|
# "schedule": {
|
||||||
|
# # 如下为刷新pillar,自动请求本接口,先测试用20s
|
||||||
|
# "job_refresh": {
|
||||||
|
# "function": "saltutil.refresh_pillar",
|
||||||
|
# "seconds": 20,
|
||||||
|
# }
|
||||||
|
# },
|
||||||
"host": host,
|
"host": host,
|
||||||
"project": projects,
|
"project": projects,
|
||||||
"channel": channels,
|
"channel": channels,
|
||||||
|
|
Loading…
Reference in New Issue