class DeployMenu(db.Model, ModelMixin): __tablename__ = 'deploy_menus' id = db.Column(db.Integer, primary_key=True) # 属于哪个应用的菜单 app_id = db.Column(db.Integer, db.ForeignKey('deploy_apps.id', ondelete='CASCADE'), nullable=True) # 菜单的显示名称 name = db.Column(db.String(50)) # 菜单的帮助及描述 desc = db.Column(db.String(255)) # 菜单展示的位置(发布: 1 / 更多: 2) position = db.Column(db.SmallInteger) # 执行结果展示方式 (页面实时输出: 1 / 仅通知成功与否: 2) display_type = db.Column(db.SmallInteger) # 执行的钩子(自定义命令) command = db.Column(db.Text) # 是否需要传入参数 required_args = db.Column(db.Boolean) # 在执行前是否需要弹框确认 required_confirm = db.Column(db.Boolean) apps = db.relationship('App', secondary='deploy_app_menu_rel') def __repr__(self): return '<DeployMenu %r>' % self.name
class JobHistory(db.Model, ModelMixin): __tablename__ = 'schedule_jobs_history' id = db.Column(db.Integer, primary_key=True) job_id = db.Column(db.Integer, db.ForeignKey('schedule_jobs.id', ondelete='CASCADE')) target = db.Column(db.String(50)) exit_code = db.Column(db.Integer) stdout = db.Column(db.Text) stderr = db.Column(db.Text) time_cost = db.Column(db.Float) created = db.Column(db.String(20)) create_time = db.Column(db.DateTime, server_default=func.now(), comment='创建时间') # onupdate设置自动更改 update_time = db.Column( db.DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='修改时间') @classmethod def write(cls, job_id, start_time, target, exit_code, stdout, stderr): cls(job_id=job_id, target=target, exit_code=exit_code, stdout=stdout[:1024], stderr=stderr[:1024], time_cost=round((datetime.now() - start_time).total_seconds(), 3), created=human_time(start_time)).save() def __repr__(self): return '<schedule.JonHistory id=%r job_id=%r>' % (self.id, self.job_id)
class Job(db.Model, ModelMixin): __tablename__ = 'schedule_jobs' id = db.Column(db.Integer, primary_key=True) bu_name = db.Column(db.String(50)) owner = db.Column(db.String(50)) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) group = db.Column(db.String(50)) command_user = db.Column(db.String(50)) command = db.Column(db.String(10000)) targets = db.Column(db.String(255)) trigger = db.Column(db.String(50)) trigger_args = db.Column(db.String(255)) enabled = db.Column(db.Boolean, default=False) create_time = db.Column(db.DateTime, server_default=func.now(), comment='创建时间') # onupdate设置自动更改 update_time = db.Column( db.DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='修改时间') def __repr__(self): return '<schedule.Job name=%r trigger=%r>' % (self.name, self.trigger)
class JobHistory(db.Model, ModelMixin): __tablename__ = 'schedule_jobs_history' id = db.Column(db.Integer, primary_key=True) job_id = db.Column(db.Integer, db.ForeignKey('schedule_jobs.id', ondelete='CASCADE')) target = db.Column(db.String(50)) exit_code = db.Column(db.Integer) stdout = db.Column(db.Text) stderr = db.Column(db.Text) time_cost = db.Column(db.Float) created = db.Column(db.String(20)) @classmethod def write(cls, job_id, start_time, target, exit_code, stdout, stderr): cls( job_id=job_id, target=target, exit_code=exit_code, stdout=stdout[:1024], stderr=stderr[:1024], time_cost=round((datetime.now() - start_time).total_seconds(), 3), created=human_time(start_time) ).save() def __repr__(self): return '<schedule.JonHistory id=%r job_id=%r>' % (self.id, self.job_id) class Meta: ordering = ('-id',)
class Service(db.Model, ModelMixin): __tablename__ = 'configuration_services' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) identify = db.Column(db.String(50), unique=True) desc = db.Column(db.String(255)) group = db.Column(db.String(50))
class Permission(db.Model, ModelMixin): __tablename__ = 'account_permissions' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True, nullable=False) desc = db.Column(db.String(255)) def __repr__(self): return '<Permission %r>' % self.name
class NoticeWay(db.Model, ModelMixin): __tablename__ = 'notice_way' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True) value = db.Column(db.Text) desc = db.Column(db.String(255)) def __repr__(self): return '<NoticeWay %r>' % self.name
class GlobalConfig(db.Model, ModelMixin): __tablename__ = 'setting_configs' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True) desc = db.Column(db.String(255)) value = db.Column(db.Text) def __repr__(self): return '<GlobalConfig %r>' % self.name
class Environment(db.Model, ModelMixin): __tablename__ = 'configuration_environments' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) identify = db.Column(db.String(50), unique=True) desc = db.Column(db.String(255)) priority = db.Column(db.Integer, default=100) def __repr__(self): return '<Environment %r>' % self.name
class HostExecTemplate(db.Model, ModelMixin): __tablename__ = 'assets_hosts_exec_template' id = db.Column(db.Integer, primary_key=True) tpl_name = db.Column(db.String(50)) tpl_desc = db.Column(db.String(255)) tpl_type = db.Column(db.String(50)) tpl_content = db.Column(db.Text()) def __repr__(self): return '<HostExecTemplate %r>' % self.tpl_name
class ImageConfig(db.Model, ModelMixin): __tablename__ = 'deploy_image_configs' id = db.Column(db.Integer, primary_key=True) img_id = db.Column(db.ForeignKey('deploy_images.id', ondelete='CASCADE')) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) value = db.Column(db.String(255)) def __repr__(self): return '<ImageConfig name=%r, value=%r>' % (self.name, self.value)
class ConfigKey(db.Model, ModelMixin): __tablename__ = 'configuration_keys' id = db.Column(db.Integer, primary_key=True) owner_type = db.Column(db.String(50)) owner_id = db.Column(db.Integer, index=True) type = db.Column(db.String(50)) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) def __repr__(self): return '<ConfigKey %r>' % self.name
class History(db.Model, ModelMixin): __tablename__ = 'deploy_history' id = db.Column(db.Integer, primary_key=True) app_id = db.Column(db.Integer, db.ForeignKey('deploy_apps.id', ondelete='CASCADE')) host_id = db.Column(db.Integer, db.ForeignKey('assets_hosts.id', ondelete='CASCADE')) env_id = db.Column(db.Integer, db.ForeignKey('configuration_environments.id', ondelete='CASCADE')) api_token = db.Column(db.String(32)) deploy_message = db.Column(db.String(255)) deploy_restart = db.Column(db.Boolean) deploy_success = db.Column(db.Boolean) created = db.Column(db.String(20))
class DeployField(db.Model, ModelMixin): __tablename__ = 'deploy_fields' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) command = db.Column(db.Text) apps = db.relationship('App', secondary='deploy_app_field_rel') def __repr__(self): return '<DeployField %r>' % self.name
class UserPriv(db.Model, ModelMixin): __tablename__ = 'user_privileges' id = db.Column(db.Integer, primary_key=True) account_id = db.Column(db.Integer, db.ForeignKey('user_accounts.id')) db_database = db.Column(db.String(128)) db_priv = db.Column(db.String(128)) __table_args__ = (db.UniqueConstraint( 'account_id', 'db_database', name='uniq_account_id_db_database'), ) def __repr__(self): return '<UserInfo %r>' % self.name
class HostExtend(db.Model, ModelMixin): __tablename__ = 'assets_hosts_extend' id = db.Column(db.Integer, primary_key=True) host_id = db.Column(db.Integer, db.ForeignKey('assets_hosts.id')) operate_system = db.Column(db.String(64)) memory = db.Column(db.SmallInteger) cpu = db.Column(db.SmallInteger) disk = db.Column(db.SmallInteger) outer_ip = db.Column(db.String(128)) inner_ip = db.Column(db.String(128)) hosts = db.relationship(Host, backref=db.backref('host'))
class UserInfo(db.Model, ModelMixin): __tablename__ = 'user_accounts' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user_hosts.id')) db_user = db.Column(db.String(128)) db_password = db.Column(db.String(128)) desc = db.Column(db.String(255)) __table_args__ = (db.Index('idx_user_id', 'user_id'), ) def __repr__(self): return '<UserInfo %r>' % self.name
class GlobalConfig(db.Model, ModelMixin): __tablename__ = 'setting_configs' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True) desc = db.Column(db.String(255)) value = db.Column(db.Text) create_time = db.Column(db.DateTime, server_default=func.now(), comment='创建时间') # onupdate设置自动更改 update_time = db.Column(db.DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='修改时间') def __repr__(self): return '<GlobalConfig %r>' % self.name
class ImageTag(db.Model, ModelMixin): __tablename__ = 'deploy_image_tags' id = db.Column(db.Integer, primary_key=True) image_id = db.Column(db.Integer, db.ForeignKey('deploy_images.id')) name = db.Column(db.String(50)) # sha256加密字符串,例如(sha256:a6647f8a2744cb8bfeff0a1b8623c8070dd92b0e6708ffa04ceb5349eaf492d6) digest = db.Column(db.String(64 + 7)) created = db.Column(db.String(20)) image = db.relationship(Image, backref=db.backref('tags')) def __repr__(self): return '<ImageTag %r>' % self.name
class AppConfigRel(db.Model, ModelMixin): __tablename__ = 'configuration_app_rel' id = db.Column(db.Integer, primary_key=True) s_id = db.Column(db.Integer, db.ForeignKey('deploy_apps.id')) d_id = db.Column(db.Integer) d_type = db.Column(db.String(50))
class User(db.Model, ModelMixin, UserMixin): __tablename__ = 'account_users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50), unique=True, nullable=False) is_supper = db.Column(db.Boolean, default=False) is_active = db.Column(db.Boolean, default=True) access_token = db.Column(db.String(32)) token_expired = db.Column(db.Integer) create_time = db.Column(db.DateTime, server_default=func.now(), comment='创建时间') update_time = db.Column( db.DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='修改时间')
class Image(db.Model, ModelMixin): __tablename__ = 'deploy_images' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True) desc = db.Column(db.String(255)) @property def latest(self): tag = ImageTag.query.filter_by(image_id=self.id).order_by(ImageTag.created.desc()).first() if not tag: raise Exception('Not has valid image tag') return tag.name def __repr__(self): return '<Image %r>' % self.name
class App(db.Model, ModelMixin): __tablename__ = 'deploy_apps' id = db.Column(db.Integer, primary_key=True) identify = db.Column(db.String(50)) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) group = db.Column(db.String(50)) image_id = db.Column(db.Integer, db.ForeignKey('deploy_images.id')) image = db.relationship(Image) menus = db.relationship('DeployMenu', secondary='deploy_app_menu_rel') fields = db.relationship('DeployField', secondary='deploy_app_field_rel') def __repr__(self): return '<App %r>' % self.name
class JobSchedule(db.Model, ModelMixin): __tablename__ = 'schedule_job_action' id = db.Column(db.Integer, primary_key=True) job_id = db.Column(db.String(2000)) owner = db.Column(db.String(100)) job_name = db.Column(db.String(500)) job_schedule_name = db.Column(db.String(500)) job_type = db.Column(db.String(500)) job_run_time = db.Column(db.String(500)) job_status = db.Column(db.String(50)) create_time = db.Column(db.DateTime, server_default=func.now(), comment='创建时间') # onupdate设置自动更改 update_time = db.Column( db.DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='修改时间') __table_args__ = (db.UniqueConstraint('job_name', 'job_schedule_name', name='job_and_schedule'), ) def __repr__(self): return '<schedule.Job_Schedule name=%r job_status=%r>' % ( self.job_name, self.job_status)
class ConfigValue(db.Model, ModelMixin): __tablename__ = 'configuration_values' id = db.Column(db.Integer, primary_key=True) env_id = db.Column(db.Integer, db.ForeignKey('configuration_environments.id')) key_id = db.Column( db.Integer, db.ForeignKey('configuration_keys.id', ondelete='CASCADE')) value = db.Column(db.String(255))
class Role(db.Model, ModelMixin): __tablename__ = 'account_roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True, nullable=False) desc = db.Column(db.String(255)) env_ids = db.Column(db.TEXT) app_ids = db.Column(db.TEXT) @staticmethod def get_permissions(role_id): sql = text( 'select p.name from account_role_permission_rel r, account_permissions p where r.role_id=%d and r.permission_id=p.id' % role_id) result = db.engine.execute(sql) return {x[0] for x in result} def __repr__(self): return '<Role %r>' % self.name
class Host(db.Model, ModelMixin): __tablename__ = 'assets_hosts' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) type = db.Column(db.String(50)) zone = db.Column(db.String(50)) ssh_ip = db.Column(db.String(32)) ssh_port = db.Column(db.Integer) create_time = db.Column(db.DateTime, server_default=func.now(), comment='创建时间') # onupdate设置自动更改 update_time = db.Column( db.DateTime, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='修改时间') def __repr__(self): return '<Host %r>' % self.name
class Job(db.Model, ModelMixin): __tablename__ = 'schedule_jobs' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) group = db.Column(db.String(50)) command_user = db.Column(db.String(50)) command = db.Column(db.String(255)) targets = db.Column(db.String(255)) trigger = db.Column(db.String(50)) trigger_args = db.Column(db.String(255)) enabled = db.Column(db.Boolean, default=False) def __repr__(self): return '<schedule.Job name=%r trigger=%r>' % (self.name, self.trigger)
class Mongodb(db.Model, ModelMixin): __tablename__ = 'mongodb_hosts' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) desc = db.Column(db.String(255)) type = db.Column(db.String(50)) zone = db.Column(db.String(50)) db_host = db.Column(db.String(255)) db_user = db.Column(db.String(128)) db_password = db.Column(db.String(128)) db_port = db.Column(db.Integer) db_database = db.Column(db.String(128)) def __repr__(self): return '<Mongodb %r>' % self.name
class User(db.Model, ModelMixin): __tablename__ = 'account_users' id = db.Column(db.Integer, primary_key=True) role_id = db.Column(db.Integer, db.ForeignKey('account_roles.id')) username = db.Column(db.String(50), unique=True, nullable=False) nickname = db.Column(db.String(50)) password_hash = db.Column(db.String(100), nullable=False) email = db.Column(db.String(120)) mobile = db.Column(db.String(30)) is_supper = db.Column(db.Boolean, default=False) type = db.Column(db.String(20), default='系统用户') is_active = db.Column(db.Boolean, default=True) access_token = db.Column(db.String(32)) token_expired = db.Column(db.Integer) role = db.relationship('Role') @property def password(self): raise AttributeError('password only can write') @password.setter def password(self, plain): self.password_hash = generate_password_hash(plain) @property def permissions(self): if self.is_supper: return set() return Role.get_permissions(self.role_id) def verify_password(self, password): return check_password_hash(self.password_hash, password) def check_deploy_permission(self, env_id, app_id): if self.is_supper: return True env_ids = self.role.env_ids.split(',') if self.role.env_ids else [] app_ids = self.role.app_ids.split(',') if self.role.app_ids else [] return str(env_id) in env_ids and str(app_id) in app_ids def __repr__(self): return '<User %r>' % self.username class Meta: ordering = ('-id', )