资产相关模型、数据库实例增删查改接口
This commit is contained in:
parent
be95b7aa5b
commit
ae5e4b5de1
|
@ -15,6 +15,7 @@ HostFields = {
|
||||||
"cpu_num": fields.Integer,
|
"cpu_num": fields.Integer,
|
||||||
"cpu_core": fields.Integer,
|
"cpu_core": fields.Integer,
|
||||||
"memory": fields.Integer,
|
"memory": fields.Integer,
|
||||||
|
"data": fields.Raw,
|
||||||
"tags": fields.List(fields.String),
|
"tags": fields.List(fields.String),
|
||||||
"labels": fields.Raw,
|
"labels": fields.Raw,
|
||||||
"created": DateTime,
|
"created": DateTime,
|
||||||
|
@ -25,3 +26,56 @@ HostSimpleFields = {
|
||||||
"public_ip": fields.String,
|
"public_ip": fields.String,
|
||||||
"private_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
|
import mongoengine as mongo
|
||||||
|
|
||||||
from common.document import DocumentBase
|
from common.document import DocumentBase
|
||||||
from common.validator import is_ipaddr
|
from common.validator import is_ipaddr, is_hex_string
|
||||||
|
|
||||||
|
|
||||||
class Host(DocumentBase):
|
class Host(DocumentBase):
|
||||||
|
@ -20,9 +21,83 @@ class Host(DocumentBase):
|
||||||
cpu_num = mongo.IntField(default=1) # cpu物理个数
|
cpu_num = mongo.IntField(default=1) # cpu物理个数
|
||||||
cpu_core = mongo.IntField(default=1) # 每个cpu的核心数
|
cpu_core = mongo.IntField(default=1) # 每个cpu的核心数
|
||||||
memory = mongo.IntField(default=0) # 内存大小,单位GB
|
memory = mongo.IntField(default=0) # 内存大小,单位GB
|
||||||
|
data = mongo.DictField(default=dict)
|
||||||
|
|
||||||
# 标记和标签
|
# 标记和标签
|
||||||
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)
|
||||||
|
|
||||||
created = mongo.DateTimeField()
|
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 import Blueprint
|
||||||
from flask_restful import Api
|
from flask_restful import Api
|
||||||
|
|
||||||
from asset import views
|
from asset.views import views
|
||||||
|
|
||||||
|
|
||||||
# 当前app的蓝图,以app名为前缀
|
# 当前app的蓝图,以app名为前缀
|
||||||
|
@ -11,3 +11,6 @@ asset_v1 = Blueprint('asset', __name__, url_prefix="/asset")
|
||||||
api = Api(asset_v1)
|
api = Api(asset_v1)
|
||||||
api.add_resource(views.HostViews, '/host/', endpoint="host")
|
api.add_resource(views.HostViews, '/host/', endpoint="host")
|
||||||
api.add_resource(views.HostDetailViews, '/host/<string:pk>/', endpoint="host-detail")
|
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 import jsonify
|
||||||
|
from flask_restful import abort
|
||||||
|
|
||||||
|
|
||||||
def make_response(status, code, msg, **kwargs):
|
def make_response(status, code, msg, **kwargs):
|
||||||
|
@ -16,3 +17,9 @@ def make_response(status, code, msg, **kwargs):
|
||||||
response = jsonify(content)
|
response = jsonify(content)
|
||||||
response.status_code = status
|
response.status_code = status
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def abort_response(status, code, **kwargs):
|
||||||
|
"""中断请求返回响应"""
|
||||||
|
abort(status, code=code, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ class RetrieveMixin(ModelViewBase):
|
||||||
|
|
||||||
class UpdateMixin(ModelViewBase):
|
class UpdateMixin(ModelViewBase):
|
||||||
|
|
||||||
def pre_update(self, obj, args):
|
def pre_update(self, obj, args: dict):
|
||||||
"""更新前钩子"""
|
"""更新前钩子"""
|
||||||
data = {}
|
data = {}
|
||||||
for k, v in args.items():
|
for k, v in args.items():
|
||||||
|
|
Loading…
Reference in New Issue