mirror of
https://github.com/veops/cmdb.git
synced 2025-08-07 07:04:58 +08:00
前后端全面升级
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from .cmdb import *
|
||||
|
@@ -13,6 +13,8 @@ from api.extensions import db
|
||||
from api.lib.database import CRUDModel
|
||||
from api.lib.database import Model
|
||||
from api.lib.database import SoftDeleteMixin
|
||||
from api.lib.perm.acl.const import ACL_QUEUE
|
||||
from api.lib.perm.acl.const import OperateType
|
||||
|
||||
|
||||
class App(Model):
|
||||
@@ -30,10 +32,13 @@ class UserQuery(BaseQuery):
|
||||
|
||||
def authenticate(self, login, password):
|
||||
user = self.filter(db.or_(User.username == login,
|
||||
User.email == login)).filter(User.deleted.is_(False)).first()
|
||||
User.email == login)).filter(User.deleted.is_(False)).filter(User.block == 0).first()
|
||||
if user:
|
||||
current_app.logger.info(user)
|
||||
authenticated = user.check_password(password)
|
||||
if authenticated:
|
||||
from api.tasks.acl import op_record
|
||||
op_record.apply_async(args=(None, login, OperateType.LOGIN, ["ACL"]), queue=ACL_QUEUE)
|
||||
else:
|
||||
authenticated = False
|
||||
|
||||
@@ -56,9 +61,11 @@ class UserQuery(BaseQuery):
|
||||
ldap_conn.protocol_version = 3
|
||||
ldap_conn.set_option(ldap.OPT_REFERRALS, 0)
|
||||
if '@' in username:
|
||||
email = username
|
||||
who = '{0}@{1}'.format(username.split('@')[0], current_app.config.get('LDAP_DOMAIN'))
|
||||
else:
|
||||
who = '{0}@{1}'.format(username, current_app.config.get('LDAP_DOMAIN'))
|
||||
email = who
|
||||
|
||||
username = username.split('@')[0]
|
||||
user = self.get_by_username(username)
|
||||
@@ -71,7 +78,10 @@ class UserQuery(BaseQuery):
|
||||
|
||||
if not user:
|
||||
from api.lib.perm.acl.user import UserCRUD
|
||||
user = UserCRUD.add(username=username, email=who)
|
||||
user = UserCRUD.add(username=username, email=email)
|
||||
|
||||
from api.tasks.acl import op_record
|
||||
op_record.apply_async(args=(None, username, OperateType.LOGIN, ["ACL"]), queue=ACL_QUEUE)
|
||||
|
||||
return user, True
|
||||
except ldap.INVALID_CREDENTIALS:
|
||||
@@ -80,28 +90,33 @@ class UserQuery(BaseQuery):
|
||||
def search(self, key):
|
||||
query = self.filter(db.or_(User.email == key,
|
||||
User.nickname.ilike('%' + key + '%'),
|
||||
User.username.ilike('%' + key + '%'))).filter(User.deleted.is_(False))
|
||||
User.username.ilike('%' + key + '%')))
|
||||
return query
|
||||
|
||||
def get_by_username(self, username):
|
||||
user = self.filter(User.username == username).filter(User.deleted.is_(False)).first()
|
||||
user = self.filter(User.username == username).first()
|
||||
|
||||
return user
|
||||
|
||||
def get_by_nickname(self, nickname):
|
||||
user = self.filter(User.nickname == nickname).filter(User.deleted.is_(False)).first()
|
||||
user = self.filter(User.nickname == nickname).first()
|
||||
|
||||
return user
|
||||
|
||||
def get_by_wxid(self, wx_id):
|
||||
user = self.filter(User.wx_id == wx_id).first()
|
||||
|
||||
return user
|
||||
|
||||
def get(self, uid):
|
||||
user = self.filter(User.uid == uid).filter(User.deleted.is_(False)).first()
|
||||
user = self.filter(User.uid == uid).first()
|
||||
|
||||
return copy.deepcopy(user)
|
||||
|
||||
|
||||
class User(CRUDModel, SoftDeleteMixin):
|
||||
__tablename__ = 'users'
|
||||
# __bind_key__ = "user"
|
||||
__bind_key__ = "user"
|
||||
query_class = UserQuery
|
||||
|
||||
uid = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
@@ -119,7 +134,9 @@ class User(CRUDModel, SoftDeleteMixin):
|
||||
block = db.Column(db.Boolean, default=False)
|
||||
has_logined = db.Column(db.Boolean, default=False)
|
||||
wx_id = db.Column(db.String(32))
|
||||
employee_id = db.Column(db.String(16), index=True)
|
||||
avatar = db.Column(db.String(128))
|
||||
# apps = db.Column(db.JSON)
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
||||
@@ -145,16 +162,65 @@ class User(CRUDModel, SoftDeleteMixin):
|
||||
def check_password(self, password):
|
||||
if self.password is None:
|
||||
return False
|
||||
return self.password == password
|
||||
return self.password == password or self.password == hashlib.md5(password.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
class RoleQuery(BaseQuery):
|
||||
def _join(self, *args, **kwargs):
|
||||
super(RoleQuery, self)._join(*args, **kwargs)
|
||||
|
||||
def authenticate(self, login, password):
|
||||
role = self.filter(Role.name == login).first()
|
||||
if role:
|
||||
authenticated = role.check_password(password)
|
||||
|
||||
if authenticated:
|
||||
from api.tasks.acl import op_record
|
||||
op_record.apply_async(args=(None, login, OperateType.LOGIN, ["ACL"]), queue=ACL_QUEUE)
|
||||
|
||||
else:
|
||||
authenticated = False
|
||||
|
||||
return role, authenticated
|
||||
|
||||
def authenticate_with_key(self, key, secret, args, path):
|
||||
role = self.filter(Role.key == key).filter(Role.deleted.is_(False)).first()
|
||||
if not role:
|
||||
return None, False
|
||||
if role and hashlib.sha1('{0}{1}{2}'.format(
|
||||
path, role.secret, "".join(args)).encode("utf-8")).hexdigest() == secret:
|
||||
authenticated = True
|
||||
else:
|
||||
authenticated = False
|
||||
|
||||
return role, authenticated
|
||||
|
||||
|
||||
class Role(Model):
|
||||
__tablename__ = "acl_roles"
|
||||
query_class = RoleQuery
|
||||
|
||||
name = db.Column(db.Text, nullable=False)
|
||||
name = db.Column(db.String(64), index=True, nullable=False)
|
||||
is_app_admin = db.Column(db.Boolean, default=False)
|
||||
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
||||
uid = db.Column(db.Integer, db.ForeignKey("users.uid"))
|
||||
uid = db.Column(db.Integer)
|
||||
_password = db.Column("password", db.String(80))
|
||||
key = db.Column(db.String(32))
|
||||
secret = db.Column(db.String(32))
|
||||
|
||||
def _get_password(self):
|
||||
return self._password
|
||||
|
||||
def _set_password(self, password):
|
||||
if password:
|
||||
self._password = hashlib.md5(password.encode('utf-8')).hexdigest()
|
||||
|
||||
password = db.synonym("_password", descriptor=property(_get_password, _set_password))
|
||||
|
||||
def check_password(self, password):
|
||||
if self.password is None:
|
||||
return False
|
||||
return self.password == password or self.password == hashlib.md5(password.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
class RoleRelation(Model):
|
||||
@@ -162,6 +228,7 @@ class RoleRelation(Model):
|
||||
|
||||
parent_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
|
||||
child_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
|
||||
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
|
||||
|
||||
|
||||
class ResourceType(Model):
|
||||
@@ -177,18 +244,24 @@ class ResourceGroup(Model):
|
||||
|
||||
name = db.Column(db.String(64), index=True, nullable=False)
|
||||
resource_type_id = db.Column(db.Integer, db.ForeignKey("acl_resource_types.id"))
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
|
||||
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
|
||||
|
||||
resource_type = db.relationship("ResourceType", backref='acl_resource_groups.resource_type_id')
|
||||
|
||||
|
||||
class Resource(Model):
|
||||
__tablename__ = "acl_resources"
|
||||
|
||||
name = db.Column(db.String(128), nullable=False)
|
||||
resource_type_id = db.Column(db.Integer, db.ForeignKey("acl_resource_types.id"))
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
|
||||
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
||||
|
||||
resource_type = db.relationship("ResourceType", backref='acl_resources.resource_type_id')
|
||||
|
||||
|
||||
class ResourceGroupItems(Model):
|
||||
__tablename__ = "acl_resource_group_items"
|
||||
@@ -196,6 +269,8 @@ class ResourceGroupItems(Model):
|
||||
group_id = db.Column(db.Integer, db.ForeignKey('acl_resource_groups.id'), nullable=False)
|
||||
resource_id = db.Column(db.Integer, db.ForeignKey('acl_resources.id'), nullable=False)
|
||||
|
||||
resource = db.relationship("Resource", backref='acl_resource_group_items.resource_id')
|
||||
|
||||
|
||||
class Permission(Model):
|
||||
__tablename__ = "acl_permissions"
|
||||
@@ -213,5 +288,90 @@ class RolePermission(Model):
|
||||
resource_id = db.Column(db.Integer, db.ForeignKey('acl_resources.id'))
|
||||
group_id = db.Column(db.Integer, db.ForeignKey('acl_resource_groups.id'))
|
||||
perm_id = db.Column(db.Integer, db.ForeignKey('acl_permissions.id'))
|
||||
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
||||
|
||||
perm = db.relationship("Permission", backref='acl_role_permissions.perm_id')
|
||||
|
||||
|
||||
class Trigger(Model):
|
||||
__tablename__ = "acl_triggers"
|
||||
|
||||
name = db.Column(db.String(128))
|
||||
wildcard = db.Column(db.Text)
|
||||
uid = db.Column(db.Text) # TODO
|
||||
resource_type_id = db.Column(db.Integer, db.ForeignKey('acl_resource_types.id'))
|
||||
roles = db.Column(db.Text) # TODO
|
||||
permissions = db.Column(db.Text) # TODO
|
||||
enabled = db.Column(db.Boolean, default=True)
|
||||
|
||||
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
|
||||
|
||||
|
||||
class OperationRecord(Model):
|
||||
__tablename__ = "acl_operation_records"
|
||||
|
||||
app = db.Column(db.String(32), index=True)
|
||||
rolename = db.Column(db.String(32), index=True)
|
||||
operate = db.Column(db.Enum(*OperateType.all()), nullable=False)
|
||||
obj = db.Column(db.JSON)
|
||||
|
||||
|
||||
class AuditRoleLog(Model):
|
||||
__tablename__ = "acl_audit_role_logs"
|
||||
|
||||
app_id = db.Column(db.Integer, index=True)
|
||||
|
||||
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
|
||||
operate_type = db.Column(db.String(32), comment='操作类型', index=True)
|
||||
scope = db.Column(db.String(16), comment='范围')
|
||||
link_id = db.Column(db.Integer, comment='资源id', index=True)
|
||||
origin = db.Column(db.JSON, default=dict(), comment='原始数据')
|
||||
current = db.Column(db.JSON, default=dict(), comment='当前数据')
|
||||
extra = db.Column(db.JSON, default=dict(), comment='其他内容')
|
||||
source = db.Column(db.String(16), default='', comment='来源')
|
||||
|
||||
|
||||
class AuditResourceLog(Model):
|
||||
__tablename__ = "acl_audit_resource_logs"
|
||||
|
||||
app_id = db.Column(db.Integer, index=True)
|
||||
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
|
||||
operate_type = db.Column(db.String(16), comment='操作类型', index=True)
|
||||
|
||||
scope = db.Column(db.String(16), comment='范围')
|
||||
link_id = db.Column(db.Integer, comment='资源名', index=True)
|
||||
origin = db.Column(db.JSON, default=dict(), comment='原始数据')
|
||||
current = db.Column(db.JSON, default=dict(), comment='当前数据')
|
||||
extra = db.Column(db.JSON, default=dict(), comment='权限名')
|
||||
source = db.Column(db.String(16), default='', comment='来源')
|
||||
|
||||
|
||||
class AuditPermissionLog(Model):
|
||||
__tablename__ = "acl_audit_permission_logs"
|
||||
|
||||
app_id = db.Column(db.Integer, index=True)
|
||||
|
||||
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
|
||||
operate_type = db.Column(db.String(16), comment='操作类型', index=True)
|
||||
|
||||
rid = db.Column(db.Integer, comment='角色id', index=True)
|
||||
resource_type_id = db.Column(db.Integer, comment='资源类型id', index=True)
|
||||
resource_ids = db.Column(db.JSON, default=[], comment='资源')
|
||||
group_ids = db.Column(db.JSON, default=[], comment='资源组')
|
||||
permission_ids = db.Column(db.JSON, default=[], comment='权限')
|
||||
source = db.Column(db.String(16), comment='来源')
|
||||
|
||||
|
||||
class AuditTriggerLog(Model):
|
||||
__tablename__ = "acl_audit_trigger_logs"
|
||||
|
||||
app_id = db.Column(db.Integer, index=True)
|
||||
|
||||
trigger_id = db.Column(db.Integer, comment='trigger', index=True)
|
||||
operate_uid = db.Column(db.Integer, comment='操作人uid', index=True)
|
||||
operate_type = db.Column(db.String(16), comment='操作类型', index=True)
|
||||
|
||||
origin = db.Column(db.JSON, default=dict(), comment='原始数据')
|
||||
current = db.Column(db.JSON, default=dict(), comment='当前数据')
|
||||
extra = db.Column(db.JSON, default=dict(), comment='权限名')
|
||||
source = db.Column(db.String(16), default='', comment='来源')
|
||||
|
@@ -3,11 +3,16 @@
|
||||
|
||||
import datetime
|
||||
|
||||
from sqlalchemy.dialects.mysql import DOUBLE
|
||||
|
||||
from api.extensions import db
|
||||
from api.lib.cmdb.const import AutoDiscoveryType
|
||||
from api.lib.cmdb.const import CIStatusEnum
|
||||
from api.lib.cmdb.const import CITypeOperateType
|
||||
from api.lib.cmdb.const import ConstraintEnum
|
||||
from api.lib.cmdb.const import OperateType
|
||||
from api.lib.cmdb.const import ValueTypeEnum
|
||||
from api.lib.database import Model
|
||||
from api.lib.database import Model, Model2
|
||||
|
||||
|
||||
# template
|
||||
@@ -22,6 +27,7 @@ class CITypeGroup(Model):
|
||||
__tablename__ = "c_ci_type_groups"
|
||||
|
||||
name = db.Column(db.String(32), nullable=False)
|
||||
order = db.Column(db.Integer, default=0)
|
||||
|
||||
|
||||
class CITypeGroupItem(Model):
|
||||
@@ -40,18 +46,22 @@ class CIType(Model):
|
||||
unique_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"), nullable=False)
|
||||
enabled = db.Column(db.Boolean, default=True, nullable=False)
|
||||
is_attached = db.Column(db.Boolean, default=False, nullable=False)
|
||||
icon_url = db.Column(db.String(256), default='', nullable=False)
|
||||
icon = db.Column(db.Text)
|
||||
order = db.Column(db.SmallInteger, default=0, nullable=False)
|
||||
default_order_attr = db.Column(db.String(33))
|
||||
|
||||
unique_key = db.relationship("Attribute", backref="c_ci_types.unique_id")
|
||||
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
|
||||
|
||||
class CITypeRelation(Model):
|
||||
__tablename__ = "c_ci_type_relations"
|
||||
|
||||
parent_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
|
||||
child_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
|
||||
parent_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False) # source
|
||||
child_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False) # dst
|
||||
relation_type_id = db.Column(db.Integer, db.ForeignKey("c_relation_types.id"), nullable=False)
|
||||
constraint = db.Column(db.Enum(*ConstraintEnum.all()), default=ConstraintEnum.One2Many)
|
||||
|
||||
parent = db.relationship("CIType", primaryjoin="CIType.id==CITypeRelation.parent_id")
|
||||
child = db.relationship("CIType", primaryjoin="CIType.id==CITypeRelation.child_id")
|
||||
@@ -73,6 +83,18 @@ class Attribute(Model):
|
||||
is_password = db.Column(db.Boolean, default=False)
|
||||
is_sortable = db.Column(db.Boolean, default=False)
|
||||
|
||||
default = db.Column(db.JSON) # {"default": None}
|
||||
|
||||
is_computed = db.Column(db.Boolean, default=False)
|
||||
compute_expr = db.Column(db.Text)
|
||||
compute_script = db.Column(db.Text)
|
||||
|
||||
choice_web_hook = db.Column(db.JSON)
|
||||
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
|
||||
option = db.Column(db.JSON)
|
||||
|
||||
|
||||
class CITypeAttribute(Model):
|
||||
__tablename__ = "c_ci_type_attributes"
|
||||
@@ -102,6 +124,23 @@ class CITypeAttributeGroupItem(Model):
|
||||
order = db.Column(db.SmallInteger, default=0)
|
||||
|
||||
|
||||
class CITypeTrigger(Model):
|
||||
# __tablename__ = "c_ci_type_triggers"
|
||||
__tablename__ = "c_c_t_t"
|
||||
|
||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'), nullable=False)
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"), nullable=False)
|
||||
notify = db.Column(db.JSON) # {subject: x, body: x, wx_to: [], mail_to: [], before_days: 0, notify_at: 08:00}
|
||||
|
||||
|
||||
class CITypeUniqueConstraint(Model):
|
||||
# __tablename__ = "c_ci_type_unique_constraints"
|
||||
__tablename__ = "c_c_t_u_c"
|
||||
|
||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'), nullable=False)
|
||||
attr_ids = db.Column(db.JSON) # [attr_id, ]
|
||||
|
||||
|
||||
# instance
|
||||
|
||||
class CI(Model):
|
||||
@@ -110,6 +149,7 @@ class CI(Model):
|
||||
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
|
||||
status = db.Column(db.Enum(*CIStatusEnum.all(), name="status"))
|
||||
heartbeat = db.Column(db.DateTime, default=lambda: datetime.datetime.now())
|
||||
is_auto_discovery = db.Column('a', db.Boolean, default=False)
|
||||
|
||||
ci_type = db.relationship("CIType", backref="c_cis.type_id")
|
||||
|
||||
@@ -132,6 +172,7 @@ class IntegerChoice(Model):
|
||||
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
|
||||
value = db.Column(db.Integer, nullable=False)
|
||||
option = db.Column(db.JSON)
|
||||
|
||||
attr = db.relationship("Attribute", backref="c_choice_integers.attr_id")
|
||||
|
||||
@@ -140,7 +181,8 @@ class FloatChoice(Model):
|
||||
__tablename__ = 'c_choice_floats'
|
||||
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
|
||||
value = db.Column(db.Float, nullable=False)
|
||||
value = db.Column(DOUBLE, nullable=False)
|
||||
option = db.Column(db.JSON)
|
||||
|
||||
attr = db.relationship("Attribute", backref="c_choice_floats.attr_id")
|
||||
|
||||
@@ -150,6 +192,7 @@ class TextChoice(Model):
|
||||
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
|
||||
value = db.Column(db.Text, nullable=False)
|
||||
option = db.Column(db.JSON)
|
||||
|
||||
attr = db.relationship("Attribute", backref="c_choice_texts.attr_id")
|
||||
|
||||
@@ -172,7 +215,7 @@ class CIIndexValueFloat(Model):
|
||||
|
||||
ci_id = db.Column(db.Integer, db.ForeignKey('c_cis.id'), nullable=False)
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
|
||||
value = db.Column(db.Float, nullable=False)
|
||||
value = db.Column(DOUBLE, nullable=False)
|
||||
|
||||
ci = db.relationship("CI", backref="c_value_index_floats.ci_id")
|
||||
attr = db.relationship("Attribute", backref="c_value_index_floats.attr_id")
|
||||
@@ -222,7 +265,7 @@ class CIValueFloat(Model):
|
||||
|
||||
ci_id = db.Column(db.Integer, db.ForeignKey('c_cis.id'), nullable=False)
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'), nullable=False)
|
||||
value = db.Column(db.Float, nullable=False)
|
||||
value = db.Column(DOUBLE, nullable=False)
|
||||
|
||||
ci = db.relationship("CI", backref="c_value_floats.ci_id")
|
||||
attr = db.relationship("Attribute", backref="c_value_floats.attr_id")
|
||||
@@ -262,7 +305,7 @@ class CIValueJson(Model):
|
||||
|
||||
|
||||
# history
|
||||
class OperationRecord(Model):
|
||||
class OperationRecord(Model2):
|
||||
__tablename__ = "c_records"
|
||||
|
||||
uid = db.Column(db.Integer, index=True, nullable=False)
|
||||
@@ -270,6 +313,8 @@ class OperationRecord(Model):
|
||||
ticket_id = db.Column(db.String(32), nullable=True)
|
||||
reason = db.Column(db.Text)
|
||||
|
||||
type_id = db.Column(db.Integer, index=True)
|
||||
|
||||
|
||||
class AttributeHistory(Model):
|
||||
__tablename__ = "c_attribute_histories"
|
||||
@@ -293,29 +338,151 @@ class CIRelationHistory(Model):
|
||||
relation_id = db.Column(db.Integer, nullable=False)
|
||||
|
||||
|
||||
class CITypeHistory(Model):
|
||||
__tablename__ = "c_ci_type_histories"
|
||||
|
||||
operate_type = db.Column(db.Enum(*CITypeOperateType.all(), name="operate_type"))
|
||||
type_id = db.Column(db.Integer, index=True, nullable=False)
|
||||
|
||||
attr_id = db.Column(db.Integer)
|
||||
trigger_id = db.Column(db.Integer)
|
||||
unique_constraint_id = db.Column(db.Integer)
|
||||
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
change = db.Column(db.JSON)
|
||||
|
||||
|
||||
# preference
|
||||
class PreferenceShowAttributes(Model):
|
||||
__tablename__ = "c_preference_show_attributes"
|
||||
# __tablename__ = "c_preference_show_attributes"
|
||||
__tablename__ = "c_psa"
|
||||
|
||||
uid = db.Column(db.Integer, index=True, nullable=False)
|
||||
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"))
|
||||
order = db.Column(db.SmallInteger, default=0)
|
||||
is_fixed = db.Column(db.Boolean, default=False)
|
||||
|
||||
ci_type = db.relationship("CIType", backref="c_preference_show_attributes.type_id")
|
||||
attr = db.relationship("Attribute", backref="c_preference_show_attributes.attr_id")
|
||||
ci_type = db.relationship("CIType", backref="c_psa.type_id")
|
||||
attr = db.relationship("Attribute", backref="c_psa.attr_id")
|
||||
|
||||
|
||||
class PreferenceTreeView(Model):
|
||||
__tablename__ = "c_preference_tree_views"
|
||||
# __tablename__ = "c_preference_tree_views"
|
||||
__tablename__ = "c_ptv"
|
||||
|
||||
uid = db.Column(db.Integer, index=True, nullable=False)
|
||||
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"), nullable=False)
|
||||
levels = db.Column(db.Text) # TODO: JSON
|
||||
levels = db.Column(db.JSON)
|
||||
|
||||
|
||||
class PreferenceRelationView(Model):
|
||||
__tablename__ = "c_preference_relation_views"
|
||||
# __tablename__ = "c_preference_relation_views"
|
||||
__tablename__ = "c_prv"
|
||||
|
||||
uid = db.Column(db.Integer, index=True, nullable=False)
|
||||
name = db.Column(db.String(64), index=True, nullable=False)
|
||||
cr_ids = db.Column(db.TEXT) # [{parent_id: x, child_id: y}] TODO: JSON
|
||||
cr_ids = db.Column(db.JSON) # [{parent_id: x, child_id: y}]
|
||||
is_public = db.Column(db.Boolean, default=False)
|
||||
|
||||
|
||||
class PreferenceSearchOption(Model):
|
||||
__tablename__ = "c_pso"
|
||||
|
||||
name = db.Column(db.String(64))
|
||||
|
||||
prv_id = db.Column(db.Integer, db.ForeignKey("c_prv.id"))
|
||||
ptv_id = db.Column(db.Integer, db.ForeignKey("c_ptv.id"))
|
||||
type_id = db.Column(db.Integer, db.ForeignKey("c_ci_types.id"))
|
||||
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
|
||||
option = db.Column(db.JSON)
|
||||
|
||||
|
||||
# custom
|
||||
class CustomDashboard(Model):
|
||||
__tablename__ = "c_c_d"
|
||||
|
||||
name = db.Column(db.String(64))
|
||||
category = db.Column(db.SmallInteger) # 0: 总数统计, 1: 字段值统计, 2: 关系统计
|
||||
enabled = db.Column(db.Boolean, default=False)
|
||||
order = db.Column(db.Integer, default=0)
|
||||
|
||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
|
||||
attr_id = db.Column(db.Integer, db.ForeignKey('c_attributes.id'))
|
||||
level = db.Column(db.Integer)
|
||||
|
||||
options = db.Column(db.JSON)
|
||||
|
||||
|
||||
class SystemConfig(Model):
|
||||
__tablename__ = "c_sc"
|
||||
|
||||
name = db.Column(db.String(64), index=True)
|
||||
option = db.Column(db.JSON)
|
||||
|
||||
|
||||
# auto discovery
|
||||
class AutoDiscoveryRule(Model):
|
||||
__tablename__ = "c_ad_rules"
|
||||
|
||||
name = db.Column(db.String(32))
|
||||
type = db.Column(db.Enum(*AutoDiscoveryType.all()), index=True)
|
||||
is_inner = db.Column(db.Boolean, default=False, index=True)
|
||||
owner = db.Column(db.Integer, index=True)
|
||||
|
||||
option = db.Column(db.JSON) # layout
|
||||
attributes = db.Column(db.JSON)
|
||||
|
||||
is_plugin = db.Column(db.Boolean, default=False)
|
||||
plugin_script = db.Column(db.Text)
|
||||
unique_key = db.Column(db.String(64))
|
||||
|
||||
|
||||
class AutoDiscoveryCIType(Model):
|
||||
__tablename__ = "c_ad_ci_types"
|
||||
|
||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
|
||||
adr_id = db.Column(db.Integer, db.ForeignKey('c_ad_ci_types.id'))
|
||||
|
||||
attributes = db.Column(db.JSON) # {ad_key: cmdb_key}
|
||||
|
||||
relation = db.Column(db.JSON) # [{ad_key: {type_id: x, attr_id: x}}]
|
||||
|
||||
auto_accept = db.Column(db.Boolean, default=False)
|
||||
|
||||
agent_id = db.Column(db.String(8), index=True)
|
||||
query_expr = db.Column(db.Text)
|
||||
|
||||
interval = db.Column(db.Integer) # seconds
|
||||
cron = db.Column(db.String(128))
|
||||
|
||||
extra_option = db.Column(db.JSON)
|
||||
uid = db.Column(db.Integer, index=True)
|
||||
|
||||
|
||||
class AutoDiscoveryCI(Model):
|
||||
__tablename__ = "c_ad_ci"
|
||||
|
||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
|
||||
adt_id = db.Column(db.Integer, db.ForeignKey('c_ad_ci_types.id'))
|
||||
unique_value = db.Column(db.String(128), index=True)
|
||||
instance = db.Column(db.JSON)
|
||||
|
||||
ci_id = db.Column(db.Integer, index=True)
|
||||
|
||||
is_accept = db.Column(db.Boolean, default=False)
|
||||
accept_by = db.Column(db.String(64), index=True)
|
||||
accept_time = db.Column(db.DateTime)
|
||||
|
||||
|
||||
class CIFilterPerms(Model):
|
||||
__tablename__ = "c_ci_filter_perms"
|
||||
|
||||
name = db.Column(db.String(64), index=True)
|
||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'))
|
||||
ci_filter = db.Column(db.Text)
|
||||
attr_filter = db.Column(db.Text)
|
||||
|
||||
rid = db.Column(db.Integer, index=True)
|
||||
|
87
cmdb-api/api/models/common_setting.py
Normal file
87
cmdb-api/api/models/common_setting.py
Normal file
@@ -0,0 +1,87 @@
|
||||
from api.extensions import db
|
||||
from api.lib.database import Model, TimestampMixin, SoftDeleteMixin, CRUDMixin
|
||||
|
||||
|
||||
class ModelWithoutPK(db.Model, TimestampMixin, SoftDeleteMixin, CRUDMixin):
|
||||
__table_args__ = {"extend_existing": True}
|
||||
__abstract__ = True
|
||||
|
||||
|
||||
class Department(ModelWithoutPK):
|
||||
__tablename__ = 'common_department'
|
||||
department_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
|
||||
department_name = db.Column(db.VARCHAR(255), default='', comment='部门名称')
|
||||
department_director_id = db.Column(
|
||||
db.Integer, default=0, comment='部门负责人ID')
|
||||
department_parent_id = db.Column(db.Integer, default=1, comment='上级部门ID')
|
||||
|
||||
sort_value = db.Column(db.Integer, default=0, comment='排序值')
|
||||
|
||||
acl_rid = db.Column(db.Integer, comment='ACL中rid', default=0)
|
||||
|
||||
|
||||
class Employee(ModelWithoutPK):
|
||||
__tablename__ = 'common_employee'
|
||||
employee_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
|
||||
email = db.Column(db.VARCHAR(255), default='', comment='邮箱')
|
||||
username = db.Column(db.VARCHAR(255), default='', comment='用户名')
|
||||
nickname = db.Column(db.VARCHAR(255), default='', comment='姓名')
|
||||
sex = db.Column(db.VARCHAR(64), default='', comment='性别')
|
||||
position_name = db.Column(db.VARCHAR(255), default='', comment='职位名称')
|
||||
mobile = db.Column(db.VARCHAR(255), default='', comment='电话号码')
|
||||
avatar = db.Column(db.VARCHAR(255), default='', comment='头像')
|
||||
|
||||
direct_supervisor_id = db.Column(db.Integer, default=0, comment='直接上级ID')
|
||||
|
||||
department_id = db.Column(db.Integer,
|
||||
db.ForeignKey('common_department.department_id'),
|
||||
comment='部门ID',
|
||||
)
|
||||
|
||||
acl_uid = db.Column(db.Integer, comment='ACL中uid', default=0)
|
||||
acl_rid = db.Column(db.Integer, comment='ACL中rid', default=0)
|
||||
acl_virtual_rid = db.Column(db.Integer, comment='ACL中虚拟角色rid', default=0)
|
||||
last_login = db.Column(db.TIMESTAMP, nullable=True, comment='上次登录时间')
|
||||
block = db.Column(db.Integer, comment='锁定状态', default=0)
|
||||
|
||||
_department = db.relationship(
|
||||
'Department', backref='common_employee.department_id',
|
||||
lazy='joined'
|
||||
)
|
||||
|
||||
|
||||
class EmployeeInfo(Model):
|
||||
"""
|
||||
员工信息
|
||||
"""
|
||||
__tablename__ = 'common_employee_info'
|
||||
|
||||
info = db.Column(db.JSON, default={}, comment='员工信息')
|
||||
employee_id = db.Column(db.Integer, db.ForeignKey(
|
||||
'common_employee.employee_id'), comment='员工ID')
|
||||
employee = db.relationship(
|
||||
'Employee', backref='common_employee.employee_id', lazy='joined')
|
||||
|
||||
|
||||
class CompanyInfo(Model):
|
||||
__tablename__ = "common_company_info_json"
|
||||
|
||||
info = db.Column(db.JSON)
|
||||
|
||||
|
||||
class InternalMessage(Model):
|
||||
"""
|
||||
内部消息
|
||||
"""
|
||||
__tablename__ = "common_internal_message"
|
||||
|
||||
title = db.Column(db.VARCHAR(255), nullable=True, comment='标题')
|
||||
content = db.Column(db.TEXT, nullable=True, comment='内容')
|
||||
path = db.Column(db.VARCHAR(255), nullable=True, comment='跳转路径')
|
||||
is_read = db.Column(db.Boolean, default=False, comment='是否已读')
|
||||
app_name = db.Column(db.VARCHAR(128), nullable=False, comment='应用名称')
|
||||
category = db.Column(db.VARCHAR(128), nullable=False, comment='分类')
|
||||
message_data = db.Column(db.JSON, nullable=True, comment='数据')
|
||||
employee_id = db.Column(db.Integer, db.ForeignKey('common_employee.employee_id'), comment='ID')
|
Reference in New Issue
Block a user