资产相关模型、数据库实例增删查改接口
This commit is contained in:
parent
be95b7aa5b
commit
ae5e4b5de1
|
@ -15,6 +15,7 @@ HostFields = {
|
|||
"cpu_num": fields.Integer,
|
||||
"cpu_core": fields.Integer,
|
||||
"memory": fields.Integer,
|
||||
"data": fields.Raw,
|
||||
"tags": fields.List(fields.String),
|
||||
"labels": fields.Raw,
|
||||
"created": DateTime,
|
||||
|
@ -25,3 +26,56 @@ HostSimpleFields = {
|
|||
"public_ip": fields.String,
|
||||
"private_ip": fields.String,
|
||||
}
|
||||
|
||||
DatabaseServerFields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"domain": fields.String,
|
||||
"host": fields.String,
|
||||
"manage": fields.String,
|
||||
"data": fields.Raw,
|
||||
"tags": fields.List(fields.String),
|
||||
"labels": fields.Raw,
|
||||
}
|
||||
|
||||
DatabaseFields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"username": fields.String,
|
||||
"password": fields.String,
|
||||
}
|
||||
|
||||
MySQLInstanceFields = {
|
||||
"port": fields.Integer,
|
||||
"username": fields.String,
|
||||
"password": fields.String,
|
||||
"storage": fields.Integer,
|
||||
"memory": fields.Integer,
|
||||
"core": fields.Integer,
|
||||
"databases": fields.List(fields.Nested(DatabaseFields))
|
||||
}
|
||||
# 合并 DatabaseServerFields
|
||||
MySQLInstanceFields.update(DatabaseServerFields)
|
||||
|
||||
RedisInstanceFields = {
|
||||
"port": fields.Integer,
|
||||
"memory": fields.Integer,
|
||||
"replicas": fields.Integer,
|
||||
"password": fields.String,
|
||||
}
|
||||
# 合并 DatabaseServerFields
|
||||
RedisInstanceFields.update(DatabaseServerFields)
|
||||
|
||||
MiddlewareFields = {
|
||||
"host": fields.String,
|
||||
"manage": fields.String,
|
||||
"data": fields.Raw,
|
||||
"tags": fields.List(fields.String),
|
||||
"labels": fields.Raw,
|
||||
}
|
||||
|
||||
NginxInstance = {
|
||||
"port": fields.Integer,
|
||||
"url": fields.String,
|
||||
}
|
||||
NginxInstance.update(MiddlewareFields)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from bson import ObjectId
|
||||
import mongoengine as mongo
|
||||
|
||||
from common.document import DocumentBase
|
||||
from common.validator import is_ipaddr
|
||||
from common.validator import is_ipaddr, is_hex_string
|
||||
|
||||
|
||||
class Host(DocumentBase):
|
||||
|
@ -20,9 +21,83 @@ class Host(DocumentBase):
|
|||
cpu_num = mongo.IntField(default=1) # cpu物理个数
|
||||
cpu_core = mongo.IntField(default=1) # 每个cpu的核心数
|
||||
memory = mongo.IntField(default=0) # 内存大小,单位GB
|
||||
data = mongo.DictField(default=dict)
|
||||
|
||||
# 标记和标签
|
||||
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
||||
labels = mongo.DictField(default=dict)
|
||||
|
||||
created = mongo.DateTimeField()
|
||||
|
||||
|
||||
class DatabaseServer(DocumentBase):
|
||||
"""数据库服务器实例,包括mysql、redis、mongodb"""
|
||||
meta = {'allow_inheritance': True}
|
||||
name = mongo.StringField(required=True)
|
||||
domain = mongo.StringField(required=False) # 域名连接的地址
|
||||
host = mongo.StringField(required=True) # 内网连接地址
|
||||
# 管理者,预留
|
||||
manage = mongo.StringField(max_length=128, required=True)
|
||||
data = mongo.DictField(default=dict)
|
||||
# 标记和标签
|
||||
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
||||
labels = mongo.DictField(default=dict)
|
||||
|
||||
|
||||
class Database(mongo.EmbeddedDocument):
|
||||
"""数据库对象的结构描述,一个数据库实例下包含多个数据库,并授权不同用户"""
|
||||
# 为数据库对象生成id,非主键
|
||||
# 查询方式: MySQLInstance.objects.filter(databases__id='61adfcd5726440e0eb8b28bc').first()
|
||||
id = mongo.ObjectIdField(required=True, default=ObjectId)
|
||||
name = mongo.StringField(required=True)
|
||||
username = mongo.StringField(default="")
|
||||
password = mongo.StringField(default="")
|
||||
|
||||
|
||||
class MySQLInstance(DatabaseServer):
|
||||
"""MySQL数据库实例"""
|
||||
# 库名、连接的用户名密码
|
||||
port = mongo.IntField(default=3306)
|
||||
username = mongo.StringField(max_length=32, required=True)
|
||||
password = mongo.StringField(max_length=128, required=True)
|
||||
# 配置
|
||||
storage = mongo.IntField(required=True)
|
||||
memory = mongo.IntField(required=True)
|
||||
core = mongo.IntField(required=True)
|
||||
# 实例数据库,包含多个数据库
|
||||
databases = mongo.EmbeddedDocumentListField(Database)
|
||||
|
||||
|
||||
class RedisInstance(DatabaseServer):
|
||||
"""Redis数据库实例"""
|
||||
# 内存大小、副本数、密码
|
||||
port = mongo.IntField(default=6379)
|
||||
memory = mongo.IntField(required=True)
|
||||
replicas = mongo.IntField(required=True, default=0)
|
||||
password = mongo.StringField(max_length=128, required=True)
|
||||
|
||||
|
||||
class Middleware(DocumentBase):
|
||||
"""中间件"""
|
||||
meta = {'allow_inheritance': True}
|
||||
host = mongo.StringField(required=True)
|
||||
# 管理者,预留
|
||||
manage = mongo.StringField(max_length=128, required=True)
|
||||
data = mongo.DictField(default=dict)
|
||||
# 标记和标签
|
||||
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
||||
labels = mongo.DictField(default=dict)
|
||||
|
||||
|
||||
class NginxInstance(Middleware):
|
||||
"""nginx服务器"""
|
||||
port = mongo.IntField(default=80)
|
||||
url = mongo.StringField(required=True)
|
||||
|
||||
|
||||
class CDN(DocumentBase):
|
||||
"""cdn域名"""
|
||||
domain = mongo.StringField(max_length=256, required=True) # cdn域名
|
||||
# 标记和标签
|
||||
tags = mongo.ListField(mongo.StringField(), default=list) # tags 默认是空列表
|
||||
labels = mongo.DictField(default=dict)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from flask import Blueprint
|
||||
from flask_restful import Api
|
||||
|
||||
from asset import views
|
||||
from asset.views import views
|
||||
|
||||
|
||||
# 当前app的蓝图,以app名为前缀
|
||||
|
@ -11,3 +11,6 @@ asset_v1 = Blueprint('asset', __name__, url_prefix="/asset")
|
|||
api = Api(asset_v1)
|
||||
api.add_resource(views.HostViews, '/host/', endpoint="host")
|
||||
api.add_resource(views.HostDetailViews, '/host/<string:pk>/', endpoint="host-detail")
|
||||
|
||||
api.add_resource(views.MySQLInstanceViews, '/database/mysql/', endpoint="db-mysql")
|
||||
api.add_resource(views.MySQLInstanceDetail, '/database/mysql/<string:pk>/', endpoint="db-mysql-detail")
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
from asset import fields
|
||||
from asset.models import Host
|
||||
|
||||
from common.views import ListCreateViewSet, DetailViewSet
|
||||
|
||||
|
||||
class HostViews(ListCreateViewSet):
|
||||
model = Host
|
||||
fields = fields.HostFields
|
||||
|
||||
|
||||
class HostDetailViews(DetailViewSet):
|
||||
model = Host
|
||||
fields = fields.HostFields
|
|
@ -0,0 +1,127 @@
|
|||
import datetime
|
||||
|
||||
from flask_restful import reqparse
|
||||
|
||||
from asset import fields
|
||||
from asset import models
|
||||
|
||||
from common.views import ListCreateViewSet, DetailViewSet
|
||||
from common.utils import abort_response
|
||||
|
||||
|
||||
class HostParse:
|
||||
model = None
|
||||
request_parse = None
|
||||
|
||||
def init_parse(self):
|
||||
self.request_parse = reqparse.RequestParser()
|
||||
# 创建时必须,修改时可选
|
||||
# self.request_parse.add_argument("public_ip", type=str, required=True,
|
||||
# help='not public_ip provided', location='json')
|
||||
self.request_parse.add_argument("private_ip", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("minion_id", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("weights", required=False, type=int, location='json')
|
||||
self.request_parse.add_argument("cpu_num", required=False, type=int, location='json')
|
||||
self.request_parse.add_argument("cpu_core", required=False, type=int, location='json')
|
||||
self.request_parse.add_argument("memory", required=False, type=int, location='json')
|
||||
self.request_parse.add_argument("tags", required=False, type=list, location='json')
|
||||
self.request_parse.add_argument("labels", required=False, type=dict, location='json')
|
||||
|
||||
def validate_or_abort(self, args, obj=None):
|
||||
"""判断是否冲突"""
|
||||
exists = self.model.objects(public_ip=args.get('public_ip', '')).first()
|
||||
if exists:
|
||||
if obj and exists.id == obj.id: # 同个对象,不算冲突
|
||||
return
|
||||
# 截断请求
|
||||
abort_response(400, 1001, msg="ip已存在")
|
||||
|
||||
def pre_create(self, args):
|
||||
# 标记创建时间
|
||||
args["created"] = datetime.datetime.now()
|
||||
self.validate_or_abort(args)
|
||||
return args
|
||||
|
||||
def pre_update(self, obj, args):
|
||||
if "created" in args:
|
||||
args.pop("created")
|
||||
self.validate_or_abort(args, obj)
|
||||
return args
|
||||
|
||||
|
||||
class HostViews(HostParse, ListCreateViewSet):
|
||||
model = models.Host
|
||||
fields = fields.HostFields
|
||||
|
||||
def __init__(self):
|
||||
self.init_parse()
|
||||
self.request_parse.add_argument("public_ip", type=str, required=True,
|
||||
help='not public_ip provided', location='json')
|
||||
super(HostViews, self).__init__()
|
||||
|
||||
|
||||
class HostDetailViews(HostParse, DetailViewSet):
|
||||
model = models.Host
|
||||
fields = fields.HostFields
|
||||
|
||||
def __init__(self):
|
||||
self.init_parse()
|
||||
self.request_parse.add_argument("public_ip", type=str, location='json')
|
||||
super(HostDetailViews, self).__init__()
|
||||
|
||||
|
||||
class DatabaseServerParse:
|
||||
model = None
|
||||
request_parse = None
|
||||
|
||||
def init_parse(self):
|
||||
self.request_parse = reqparse.RequestParser()
|
||||
self.request_parse.add_argument("domain", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("tags", required=False, type=list, location='json')
|
||||
self.request_parse.add_argument("labels", required=False, type=dict, location='json')
|
||||
|
||||
|
||||
class RedisInstanceParse(DatabaseServerParse):
|
||||
|
||||
def init_parse(self):
|
||||
super(RedisInstanceParse, self).init_parse()
|
||||
self.request_parse.add_argument("port", required=False, type=int, location='json')
|
||||
|
||||
|
||||
class MySQLInstanceViews(DatabaseServerParse, ListCreateViewSet):
|
||||
model = models.MySQLInstance
|
||||
fields = fields.MySQLInstanceFields
|
||||
|
||||
def __init__(self):
|
||||
self.init_parse()
|
||||
self.request_parse.add_argument("name", required=True, type=str, location='json')
|
||||
self.request_parse.add_argument("host", required=True, type=str, location='json')
|
||||
self.request_parse.add_argument("manage", required=True, type=str, location='json')
|
||||
|
||||
self.request_parse.add_argument("port", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("username", required=True, type=str, location='json')
|
||||
self.request_parse.add_argument("password", required=True, type=str, location='json')
|
||||
self.request_parse.add_argument("storage", required=True, type=int, location='json')
|
||||
self.request_parse.add_argument("memory", required=True, type=int, location='json')
|
||||
self.request_parse.add_argument("core", required=True, type=int, location='json')
|
||||
super(MySQLInstanceViews, self).__init__()
|
||||
|
||||
|
||||
class MySQLInstanceDetail(DatabaseServerParse, DetailViewSet):
|
||||
model = models.MySQLInstance
|
||||
fields = fields.MySQLInstanceFields
|
||||
|
||||
def __init__(self):
|
||||
"""对象修改的参数解析"""
|
||||
self.init_parse()
|
||||
self.request_parse.add_argument("host", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("name", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("manage", required=False, type=str, location='json')
|
||||
|
||||
self.request_parse.add_argument("port", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("username", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("password", required=False, type=str, location='json')
|
||||
self.request_parse.add_argument("storage", required=False, type=int, location='json')
|
||||
self.request_parse.add_argument("memory", required=False, type=int, location='json')
|
||||
self.request_parse.add_argument("core", required=False, type=int, location='json')
|
||||
super(MySQLInstanceDetail, self).__init__()
|
|
@ -1,4 +1,5 @@
|
|||
from flask import jsonify
|
||||
from flask_restful import abort
|
||||
|
||||
|
||||
def make_response(status, code, msg, **kwargs):
|
||||
|
@ -16,3 +17,9 @@ def make_response(status, code, msg, **kwargs):
|
|||
response = jsonify(content)
|
||||
response.status_code = status
|
||||
return response
|
||||
|
||||
|
||||
def abort_response(status, code, **kwargs):
|
||||
"""中断请求返回响应"""
|
||||
abort(status, code=code, **kwargs)
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ class RetrieveMixin(ModelViewBase):
|
|||
|
||||
class UpdateMixin(ModelViewBase):
|
||||
|
||||
def pre_update(self, obj, args):
|
||||
def pre_update(self, obj, args: dict):
|
||||
"""更新前钩子"""
|
||||
data = {}
|
||||
for k, v in args.items():
|
||||
|
|
Loading…
Reference in New Issue