区服信息接口基础实现
1. 新增区服信息接口(可按机器minion_id请求查询) 2. 时间字段格式化封装 3. 模型调整,返回的字段有调整,针对字段组合又常用的写入模型property来格式化,接口返回不方便处理
This commit is contained in:
parent
a2fd364343
commit
ce0c1a0cb4
|
@ -3,6 +3,7 @@ asset marshal fields
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask_restful import fields
|
from flask_restful import fields
|
||||||
|
from common.fields import DateTime
|
||||||
|
|
||||||
|
|
||||||
HostFields = {
|
HostFields = {
|
||||||
|
@ -16,7 +17,7 @@ HostFields = {
|
||||||
"memory": fields.Integer,
|
"memory": fields.Integer,
|
||||||
"tags": fields.List(fields.String),
|
"tags": fields.List(fields.String),
|
||||||
"labels": fields.Raw,
|
"labels": fields.Raw,
|
||||||
"created": fields.DateTime,
|
"created": DateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
HostSimpleFields = {
|
HostSimpleFields = {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
from flask_restful import fields
|
||||||
|
|
||||||
|
|
||||||
|
class DateTime(fields.DateTime):
|
||||||
|
"""时间字段格式化,默认的 `rfc822` 不直观,可以指定 `dt_format` 自定义格式"""
|
||||||
|
|
||||||
|
def __init__(self, dt_format='%Y-%m-%d %H:%M:%S', **kwargs):
|
||||||
|
super(fields.DateTime, self).__init__(**kwargs)
|
||||||
|
self.dt_format = dt_format
|
||||||
|
|
||||||
|
def format(self, value):
|
||||||
|
try:
|
||||||
|
if self.dt_format in ('rfc822', 'iso8601'):
|
||||||
|
return super(fields.DateTime.format(self, value))
|
||||||
|
else:
|
||||||
|
if isinstance(value, str):
|
||||||
|
return value
|
||||||
|
return value.strftime(self.dt_format)
|
||||||
|
except AttributeError as ae:
|
||||||
|
raise fields.MarshallingException(ae)
|
|
@ -9,6 +9,7 @@ ProjectFields = {
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"name": fields.String,
|
"name": fields.String,
|
||||||
"fork": fields.String,
|
"fork": fields.String,
|
||||||
|
"fullname": fields.String,
|
||||||
"domain": fields.String,
|
"domain": fields.String,
|
||||||
"www_ip": fields.String,
|
"www_ip": fields.String,
|
||||||
"ops_ip": fields.String,
|
"ops_ip": fields.String,
|
||||||
|
@ -25,6 +26,7 @@ ProjectSimpleField = {
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"name": fields.String,
|
"name": fields.String,
|
||||||
"fork": fields.String,
|
"fork": fields.String,
|
||||||
|
"fullname": fields.String,
|
||||||
"domain": fields.String,
|
"domain": fields.String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +60,7 @@ ChannelSimpleFields = {
|
||||||
ServerFields = {
|
ServerFields = {
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"num": fields.Integer,
|
"num": fields.Integer,
|
||||||
|
"agent": fields.String,
|
||||||
"channel": fields.Nested(ChannelSimpleFields),
|
"channel": fields.Nested(ChannelSimpleFields),
|
||||||
"status": fields.String,
|
"status": fields.String,
|
||||||
"host": fields.Nested(HostSimpleFields),
|
"host": fields.Nested(HostSimpleFields),
|
||||||
|
@ -66,6 +69,27 @@ ServerFields = {
|
||||||
"version": fields.Nested(VersionFields),
|
"version": fields.Nested(VersionFields),
|
||||||
"weight": fields.Integer,
|
"weight": fields.Integer,
|
||||||
"slot": fields.Integer,
|
"slot": fields.Integer,
|
||||||
"tag": fields.List(fields.String),
|
"tags": fields.List(fields.String),
|
||||||
"labels": fields.Raw,
|
"labels": fields.Raw,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 主要关联字段平铺了的区服信息
|
||||||
|
AgentServerFields = {
|
||||||
|
"id": fields.String,
|
||||||
|
"num": fields.Integer,
|
||||||
|
"spid": fields.String,
|
||||||
|
"agent": fields.String,
|
||||||
|
# "channel_id": fields.String,
|
||||||
|
"project": fields.String,
|
||||||
|
"public_ip": fields.String,
|
||||||
|
"private_ip": fields.String,
|
||||||
|
# "host_id": fields.String,
|
||||||
|
"domain": fields.String,
|
||||||
|
"port": fields.Integer,
|
||||||
|
"version": fields.Nested(VersionFields),
|
||||||
|
"status": fields.String,
|
||||||
|
"weight": fields.Integer,
|
||||||
|
"slot": fields.Integer,
|
||||||
|
# "tags": fields.List(fields.String),
|
||||||
|
# "labels": fields.Raw,
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ class Project(DocumentBase):
|
||||||
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
||||||
labels = mongo.DictField(default=dict)
|
labels = mongo.DictField(default=dict)
|
||||||
|
|
||||||
|
@property
|
||||||
def fullname(self):
|
def fullname(self):
|
||||||
return f"{self.name}/{self.fork}"
|
return f"{self.name}/{self.fork}"
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ class Server(DocumentBase):
|
||||||
|
|
||||||
# 机器字段,TODO 先允许为空
|
# 机器字段,TODO 先允许为空
|
||||||
host = mongo.ReferenceField(Host, null=True)
|
host = mongo.ReferenceField(Host, null=True)
|
||||||
domain = mongo.StringField(max_length=128, required=False)
|
domain = mongo.StringField(max_length=128, required=False, default="")
|
||||||
port = mongo.IntField()
|
port = mongo.IntField()
|
||||||
version = mongo.EmbeddedDocumentField(Version)
|
version = mongo.EmbeddedDocumentField(Version)
|
||||||
weight = mongo.IntField(default=1)
|
weight = mongo.IntField(default=1)
|
||||||
|
@ -86,3 +87,44 @@ class Server(DocumentBase):
|
||||||
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
||||||
labels = mongo.DictField(default=dict)
|
labels = mongo.DictField(default=dict)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def agent(self):
|
||||||
|
if self.channel:
|
||||||
|
return f"{self.channel.spid}_s{self.num}"
|
||||||
|
return f"_s{self.num}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def spid(self):
|
||||||
|
if self.channel:
|
||||||
|
return self.channel.spid
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def channel_id(self):
|
||||||
|
if self.channel:
|
||||||
|
return self.channel.id
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project(self):
|
||||||
|
if self.channel:
|
||||||
|
return self.channel.project.fullname
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def public_ip(self):
|
||||||
|
if self.host:
|
||||||
|
return self.host.public_ip
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def private_ip(self):
|
||||||
|
if self.host:
|
||||||
|
return self.host.private_ip
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def host_id(self):
|
||||||
|
if self.host:
|
||||||
|
return self.host.id
|
||||||
|
return ""
|
||||||
|
|
|
@ -22,3 +22,6 @@ api.add_resource(views.ServerViews, '/server/', endpoint="server")
|
||||||
api.add_resource(views.ServerDetailView, '/server/<string:pk>/', endpoint="server-detail")
|
api.add_resource(views.ServerDetailView, '/server/<string:pk>/', endpoint="server-detail")
|
||||||
# 区服信息同步接口,更新区服信息
|
# 区服信息同步接口,更新区服信息
|
||||||
api.add_resource(operation.ServerSyncView, '/server/sync/', endpoint="server-sync")
|
api.add_resource(operation.ServerSyncView, '/server/sync/', endpoint="server-sync")
|
||||||
|
|
||||||
|
# 机器信息
|
||||||
|
api.add_resource(operation.AgentInfo, '/agent/info/<string:agent_id>/', endpoint="agent-info")
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
from flask_restful import reqparse
|
from flask_restful import reqparse, Resource, marshal, fields as F
|
||||||
|
|
||||||
from asset.models import Host
|
from asset.models import Host
|
||||||
|
from asset.fields import HostFields
|
||||||
from project import fields
|
from project import fields
|
||||||
from project.models import Project, Channel, Server, Version
|
from project.models import Project, Channel, Server, Version
|
||||||
from common.views import CreateMixin
|
from common.views import CreateMixin, RetrieveMixin
|
||||||
from common.permission import token_header_required
|
from common.permission import token_header_required
|
||||||
from common.utils import make_response
|
from common.utils import make_response
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ class ServerSyncView(CreateMixin):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not host:
|
if not host:
|
||||||
proj = self.project.fullname()
|
proj = self.project.fullname
|
||||||
hostObj, created = Host.get_or_create(
|
hostObj, created = Host.get_or_create(
|
||||||
public_ip=ip, defaults=dict(public_ip=ip, tags=[proj], created=datetime.datetime.now()))
|
public_ip=ip, defaults=dict(public_ip=ip, tags=[proj], created=datetime.datetime.now()))
|
||||||
# 项目写入机器的tags
|
# 项目写入机器的tags
|
||||||
|
@ -114,3 +115,33 @@ class ServerSyncView(CreateMixin):
|
||||||
|
|
||||||
return make_response(200, 1000, "success")
|
return make_response(200, 1000, "success")
|
||||||
|
|
||||||
|
|
||||||
|
class AgentInfo(RetrieveMixin):
|
||||||
|
"""返回对应机器的所有信息:项目、渠道、区服内容"""
|
||||||
|
fields = {
|
||||||
|
"host": F.Nested(HostFields),
|
||||||
|
"project": F.List(F.Nested(fields.ProjectFields)),
|
||||||
|
"channel": F.List(F.Nested(fields.ChannelFields)),
|
||||||
|
"servers": F.List(F.Nested(fields.AgentServerFields))
|
||||||
|
}
|
||||||
|
|
||||||
|
def get(self, agent_id):
|
||||||
|
"""
|
||||||
|
:param agent_id: 客户端 id
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
# 找到机器,不存在就404
|
||||||
|
host = Host.objects(minion_id=agent_id).first_or_404(message="resource not found")
|
||||||
|
# 根据机器找区服集合,返回
|
||||||
|
servers = Server.objects(host=host).all()
|
||||||
|
channels = servers.values_list("channel").distinct("channel")
|
||||||
|
projects = [channel.project for channel in channels]
|
||||||
|
# 填充数据
|
||||||
|
data = {
|
||||||
|
"host": host,
|
||||||
|
"project": projects,
|
||||||
|
"channel": channels,
|
||||||
|
"servers": servers,
|
||||||
|
}
|
||||||
|
# 返回
|
||||||
|
return marshal(data, self.fields)
|
||||||
|
|
Loading…
Reference in New Issue