├── .gitattributes ├── .gitignore ├── config.py ├── images ├── ad_user_list.png ├── alert_count.png ├── cmdb_server_list.png ├── index.png ├── login_page.jpg ├── zeus_build.png ├── zeus_build_list.png ├── zeus_config.png ├── zeus_project_list.png └── zeus_server.png ├── manage.py ├── opsweb ├── __init__.py ├── ad │ ├── __init__.py │ ├── ad_group.py │ ├── ad_user.py │ └── ldap_conn.py ├── auth │ ├── __init__.py │ ├── admin.py │ ├── crowd.py │ └── login.py ├── cmdb │ ├── __init__.py │ ├── cloud_privilege.py │ ├── cloud_project.py │ ├── cmdb_apis.py │ ├── cmdb_user.py │ ├── kvm_privilege.py │ ├── kvm_project.py │ ├── project.py │ ├── server_cloudvps.py │ ├── server_physical.py │ ├── server_privilege.py │ ├── server_project.py │ ├── server_vps.py │ └── user_project_privilege.py ├── dao │ ├── __init__.py │ ├── db_cmdb_ad_user.py │ ├── db_cmdb_cloud_project.py │ ├── db_cmdb_cloud_user.py │ ├── db_cmdb_cloud_virtual_server.py │ ├── db_cmdb_kvm_project.py │ ├── db_cmdb_kvm_user.py │ ├── db_cmdb_kvm_virtual_server.py │ ├── db_cmdb_lanip.py │ ├── db_cmdb_physical_server.py │ ├── db_cmdb_physical_server_project.py │ ├── db_cmdb_physics_server_user.py │ ├── db_cmdb_project.py │ ├── db_cmdb_project_user.py │ ├── db_cmdb_user.py │ ├── db_cmdb_wanip.py │ ├── db_zeus_project.py │ ├── db_zeus_project_build.py │ ├── db_zeus_project_config.py │ ├── db_zeus_project_deploy_job.py │ ├── db_zeus_project_deploy_task.py │ ├── db_zeus_project_server.py │ ├── db_zeus_user_info.py │ └── db_zeus_user_privilege.py ├── static │ ├── css │ │ ├── bootstrap-select.min.css │ │ ├── bootstrap.min.css │ │ ├── custom.css │ │ ├── dataTables.bootstrap.css │ │ ├── dataTables.responsive.css │ │ ├── font-awesome.min.css │ │ ├── metisMenu.min.css │ │ ├── morris.css │ │ └── sb-admin-2.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── images │ │ ├── sort_asc.png │ │ ├── sort_asc_disabled.png │ │ ├── sort_both.png │ │ ├── sort_desc.png │ │ └── sort_desc_disabled.png │ └── js │ │ ├── bootstrap-select.min.js │ │ ├── bootstrap.min.js │ │ ├── dataTables.bootstrap.min.js │ │ ├── dataTables.responsive.js │ │ ├── jquery.dataTables.min.js │ │ ├── jquery.min.js │ │ ├── metisMenu.min.js │ │ ├── morris-data.js │ │ ├── morris.min.js │ │ ├── raphael.min.js │ │ └── sb-admin-2.js ├── statistics │ ├── __init__.py │ └── confluence_stat.py ├── templates │ ├── ad_group_list.html │ ├── ad_group_member_add.html │ ├── ad_group_member_list.html │ ├── ad_user_add.html │ ├── ad_user_detail.html │ ├── ad_user_edit.html │ ├── ad_user_list.html │ ├── ad_user_reset_pwd.html │ ├── cmdb_cloud_privilege_add.html │ ├── cmdb_cloud_privilege_list.html │ ├── cmdb_cloud_project_add.html │ ├── cmdb_cloud_project_list.html │ ├── cmdb_kvm_privilege_add.html │ ├── cmdb_kvm_privilege_list.html │ ├── cmdb_kvm_project_add.html │ ├── cmdb_kvm_project_list.html │ ├── cmdb_project_add.html │ ├── cmdb_project_edit.html │ ├── cmdb_project_list.html │ ├── cmdb_project_privilege_add.html │ ├── cmdb_project_privilege_edit.html │ ├── cmdb_project_privilege_list.html │ ├── cmdb_server_cloudvps_add.html │ ├── cmdb_server_cloudvps_detail.html │ ├── cmdb_server_cloudvps_edit.html │ ├── cmdb_server_cloudvps_list.html │ ├── cmdb_server_physical_add.html │ ├── cmdb_server_physical_detail.html │ ├── cmdb_server_physical_edit.html │ ├── cmdb_server_physical_list.html │ ├── cmdb_server_privilege_add.html │ ├── cmdb_server_privilege_edit.html │ ├── cmdb_server_privilege_list.html │ ├── cmdb_server_project_add.html │ ├── cmdb_server_project_list.html │ ├── cmdb_server_vps_add.html │ ├── cmdb_server_vps_detail.html │ ├── cmdb_server_vps_edit.html │ ├── cmdb_server_vps_list.html │ ├── cmdb_user_add.html │ ├── cmdb_user_edit.html │ ├── cmdb_user_list.html │ ├── include │ │ ├── header.html │ │ └── menu.html │ ├── index.html │ ├── login.html │ ├── zeus_project_build_create.html │ ├── zeus_project_build_list.html │ ├── zeus_project_build_view.html │ ├── zeus_project_config_edit.html │ ├── zeus_project_config_list.html │ ├── zeus_project_create.html │ ├── zeus_project_deploy_deploy.html │ ├── zeus_project_deploy_log.html │ ├── zeus_project_edit.html │ ├── zeus_project_list.html │ ├── zeus_project_server_list.html │ ├── zeus_user_info.html │ ├── zeus_user_info_edit.html │ ├── zeus_user_privilege.html │ └── zeus_user_privilege_edit.html ├── utils │ ├── __init__.py │ ├── check_privilege.py │ ├── get_flash_alert_msg.py │ ├── ip_change.py │ ├── json_helper.py │ ├── user_zeus_privilege.py │ └── validate_ip.py ├── views │ ├── __init__.py │ └── index.py ├── zabbix │ ├── __init__.py │ └── zbx_api.py └── zeus │ ├── __init__.py │ ├── job │ ├── __init__.py │ ├── build_job.py │ └── deploy_job.py │ ├── project.py │ ├── project_build.py │ ├── project_config.py │ ├── project_deploy.py │ ├── project_server.py │ └── user_info.py ├── readme.md └── requirements.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=Python 2 | *.css linguist-language=Python 3 | *.html linguist-language=Python 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | share 2 | *.log 3 | .settings 4 | .project 5 | .pydevproject 6 | .DS_Store 7 | .idea 8 | *.pyc 9 | *__pycache__* 10 | venv 11 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | class Config(object): 5 | SECRET_KEY = 'aaaaaaaaxxxxxxxxxxxxxx' 6 | LOGPATH = "/data/logs/ops-web/stdout.log" 7 | LDAP_SERVER = '根据实际填写' 8 | LDAP_ADM_USER = '根据实际填写' 9 | LDAP_ADM_PSW = '根据实际填写' 10 | LDAP_PORT = 389 11 | LDAP_BASE_PATH = '根据实际填写' 12 | LDAP_DEFAULT_SEARCH_FILTER = '根据实际填写' 13 | LDAP_OBJECT_CLASS = '根据实际填写' 14 | CROWD_URL = '根据实际填写' 15 | CROWD_APP = '根据实际填写' 16 | CROWD_PSW = '根据实际填写' 17 | ZBX_ADMIN_USER = '根据实际填写' 18 | ZBX_ADMIN_PSW = '根据实际填写' 19 | ZBX_URL = '根据实际填写' 20 | SQLALCHEMY_COMMIT_ON_TEARDOWN = True 21 | SQLALCHEMY_TRACK_MODIFICATIONS = True 22 | ES_CONFLUENCE_URL = '根据实际填写' 23 | 24 | IS_NOT_ADMIN = '只有管理员角色有操作权限' 25 | USER_LOGIN_ERROR = '用户名或密码不正确,请重新登录' 26 | USER_LOGIN_PRIVILEGE_ERROR = '没有登录权限' 27 | HAS_NO_PROJECT_PRIVILEGE = '没有项目权限' 28 | IS_NOT_AD_ADMIN = '您没有LDAP操作权限' 29 | IS_NOT_ZEUS_ADMIN = '您没有ZEUS操作权限' 30 | IS_NOT_CMDB_ADMIN = '您没有CMDB操作权限' 31 | DATA_EXIST = '数据已经存在' 32 | LDAP_REQUEST_ERROR = '与AD服务器的连接发生错误,LDAP请求失败' 33 | MYSQL_REQUEST_ERROR = '与MySQL服务器的连接发生错误,MySQL请求失败' 34 | IP_FORMAT_ERROR = 'IP地址格式不正确' 35 | 36 | @staticmethod 37 | def init_app(app): 38 | pass 39 | 40 | 41 | class TestingConfig(Config): 42 | SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://test:test@1.1.1.1/cmdb' 43 | SQLALCHEMY_BINDS = {'cmdb': 'mysql+pymysql://test:test@1.1.1.1/cmdb', 44 | 'zeus': 'mysql+pymysql://test:test@1.1.1.1/zeus'} 45 | 46 | 47 | class PreReleaseConfig(Config): 48 | SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://pre:pre@1.1.1.1/cmdb' 49 | SQLALCHEMY_BINDS = {'cmdb': 'mysql+pymysql://pre:pre@1.1.1.1/cmdb', 50 | 'zeus': 'mysql+pymysql://pre:pre@1.1.1.1/zeus'} 51 | 52 | 53 | class ProductionConfig(Config): 54 | pass 55 | 56 | 57 | config = { 58 | 'testing': TestingConfig, 59 | 'pre-release': PreReleaseConfig, 60 | 'production': ProductionConfig 61 | } 62 | -------------------------------------------------------------------------------- /images/ad_user_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/ad_user_list.png -------------------------------------------------------------------------------- /images/alert_count.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/alert_count.png -------------------------------------------------------------------------------- /images/cmdb_server_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/cmdb_server_list.png -------------------------------------------------------------------------------- /images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/index.png -------------------------------------------------------------------------------- /images/login_page.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/login_page.jpg -------------------------------------------------------------------------------- /images/zeus_build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/zeus_build.png -------------------------------------------------------------------------------- /images/zeus_build_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/zeus_build_list.png -------------------------------------------------------------------------------- /images/zeus_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/zeus_config.png -------------------------------------------------------------------------------- /images/zeus_project_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/zeus_project_list.png -------------------------------------------------------------------------------- /images/zeus_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/images/zeus_server.png -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import create_app 3 | 4 | app = create_app() 5 | 6 | if __name__ == '__main__': 7 | app.run(debug=True, host='0.0.0.0', port=5000) 8 | -------------------------------------------------------------------------------- /opsweb/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask import Flask 3 | from flask_sqlalchemy import SQLAlchemy 4 | from flask_login import LoginManager 5 | from config import config 6 | from logging.handlers import RotatingFileHandler 7 | import logging 8 | 9 | db_cmdb = SQLAlchemy() 10 | db_zeus = SQLAlchemy() 11 | 12 | login_manager = LoginManager() 13 | login_manager.login_view = 'auth.login' 14 | login_manager.login_message = u"请登录!" 15 | 16 | 17 | def create_app(): 18 | app = Flask(__name__, template_folder='templates') 19 | app.config.from_object(config['pre-release']) 20 | config['pre-release'].init_app(app) 21 | 22 | db_cmdb.init_app(app) 23 | db_zeus.init_app(app) 24 | login_manager.init_app(app) 25 | 26 | logpath = app.config['LOGPATH'] 27 | handler = RotatingFileHandler(logpath, mode='w', maxBytes=10 * 1024 * 1024, backupCount=20, encoding='UTF-8') 28 | formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(funcName)s - %(message)s') 29 | handler.setFormatter(formatter) 30 | app.logger.addHandler(handler) 31 | app.logger.setLevel(logging.INFO) 32 | 33 | from .cmdb import cmdb, cmdb_api 34 | from .auth import auth 35 | from .ad import ad 36 | from .views import views 37 | from .statistics import statistics 38 | from .zeus import zeus 39 | 40 | app.register_blueprint(cmdb, url_prefix='/cmdb') 41 | app.register_blueprint(cmdb_api, url_prefix='/cmdb/api') 42 | app.register_blueprint(auth, url_prefix='/auth') 43 | app.register_blueprint(ad, url_prefix='/ad') 44 | app.register_blueprint(zeus, url_prefix='/zeus') 45 | app.register_blueprint(views, url_prefix='/') 46 | app.register_blueprint(statistics, url_prefix='/statistics') 47 | 48 | return app 49 | -------------------------------------------------------------------------------- /opsweb/ad/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | ad = Blueprint('ad', __name__) 4 | 5 | from . import ad_group, ad_user -------------------------------------------------------------------------------- /opsweb/ad/ad_group.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask import render_template, current_app, request, redirect, url_for, flash 3 | from ldap3 import MODIFY_ADD, MODIFY_DELETE 4 | from flask_login import login_required, current_user 5 | from .ldap_conn import LDAPConn 6 | from ..ad import ad 7 | from ..auth.admin import is_ad_admin 8 | 9 | 10 | @ad.route('/group/list', methods=['GET']) 11 | @login_required 12 | def ad_group_list(): 13 | search_filter = '(objectClass=group)' 14 | _ldap_base_path = current_app.config['LDAP_BASE_PATH'] 15 | try: 16 | ldap_conn = LDAPConn() 17 | ldap_conn = ldap_conn.ldap_conn() 18 | ldap_conn.bind() 19 | ldap_conn.search(search_base=_ldap_base_path, search_filter=search_filter, attributes=['*']) 20 | ad_groups = ldap_conn.entries 21 | except Exception as e: 22 | current_app.logger.error('Error: {}'.format(e)) 23 | flash(current_app.config['LDAP_REQUEST_ERROR'], 'alert') 24 | return redirect(request.referrer) 25 | else: 26 | ldap_conn.unbind() 27 | return render_template('ad_group_list.html', ad_groups=ad_groups) 28 | 29 | 30 | @ad.route('/group/member/list', methods=['GET']) 31 | @login_required 32 | @is_ad_admin 33 | def ad_group_member_list(): 34 | group_cn = request.args.get('groupCN') 35 | search_filter = '(cn=' + group_cn + ')' 36 | _ldap_base_path = current_app.config['LDAP_BASE_PATH'] 37 | try: 38 | ldap_conn = LDAPConn() 39 | ldap_conn = ldap_conn.ldap_conn() 40 | ldap_conn.bind() 41 | ldap_conn.search(search_base=_ldap_base_path, search_filter=search_filter, attributes=['*']) 42 | ad_group = ldap_conn.entries 43 | group = ad_group[0] 44 | except Exception as e: 45 | current_app.logger.error('Error: {}'.format(e)) 46 | flash(current_app.config['LDAP_REQUEST_ERROR'], 'alert') 47 | return redirect(request.referrer) 48 | else: 49 | ldap_conn.unbind() 50 | return render_template('ad_group_member_list.html', members=group.member, group_cn=group_cn) 51 | 52 | 53 | @ad.route('/group/member/add', methods=['GET', 'POST']) 54 | @login_required 55 | @is_ad_admin 56 | def ad_group_member_add(): 57 | if request.method == 'GET': 58 | group_cn = request.args.get('groupCN') 59 | return render_template('ad_group_member_add.html', group_cn=group_cn) 60 | if request.method == 'POST': 61 | member = request.form['member'] 62 | group_cn = request.form['groupCN'] 63 | _ldap_base_path = current_app.config['LDAP_BASE_PATH'] 64 | dn = 'CN=' + member + ',' + _ldap_base_path 65 | group_dn = 'CN=' + group_cn + ',' + _ldap_base_path 66 | group_change = {'member': [MODIFY_ADD, dn]} 67 | try: 68 | ldap_conn = LDAPConn() 69 | ldap_conn = ldap_conn.ldap_conn() 70 | ldap_conn.bind() 71 | ldap_conn.modify(group_dn, group_change) 72 | except Exception as e: 73 | current_app.logger.error('Error: {}'.format(e)) 74 | flash(current_app.config['LDAP_REQUEST_ERROR'], 'alert') 75 | return redirect(request.referrer) 76 | else: 77 | ldap_conn.unbind() 78 | return redirect(url_for("ad.ad_group_member_list", groupCN=group_cn)) 79 | 80 | 81 | @ad.route('/group/member/del', methods=['GET']) 82 | @login_required 83 | @is_ad_admin 84 | def ad_group_member_del(): 85 | group_cn = request.args.get('groupCN') 86 | member_dn = request.args.get('member') 87 | _ldap_base_path = current_app.config['LDAP_BASE_PATH'] 88 | group_dn = 'CN=' + group_cn + ',' + _ldap_base_path 89 | group_change = {'member': [MODIFY_DELETE, member_dn]} 90 | try: 91 | ldap_conn = LDAPConn() 92 | ldap_conn = ldap_conn.ldap_conn() 93 | ldap_conn.bind() 94 | ldap_conn.modify(group_dn, group_change) 95 | except Exception as e: 96 | current_app.logger.error('Error: {}'.format(e)) 97 | flash(current_app.config['LDAP_REQUEST_ERROR'], 'alert') 98 | return redirect(request.referrer) 99 | else: 100 | ldap_conn.unbind() 101 | return redirect(url_for("ad.ad_group_member_list", groupCN=group_cn)) 102 | -------------------------------------------------------------------------------- /opsweb/ad/ldap_conn.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask import current_app 3 | from ldap3 import Server, Connection, ALL 4 | 5 | 6 | class LDAPConn(object): 7 | def __init__(self): 8 | self._host = current_app.config['LDAP_SERVER'] 9 | self._user = current_app.config['LDAP_ADM_USER'] 10 | self._password = current_app.config['LDAP_ADM_PSW'] 11 | self.ldap_server = Server(self._host, use_ssl=True, get_info=ALL) 12 | 13 | def ldap_conn(self): 14 | try: 15 | conn = Connection(self.ldap_server, self._user, self._password) 16 | except Exception as e: 17 | current_app.logger.exception('crowd connection error: '.format(e)) 18 | return None 19 | else: 20 | return conn 21 | -------------------------------------------------------------------------------- /opsweb/auth/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | auth = Blueprint('auth', __name__) 4 | 5 | from . import admin, crowd, login -------------------------------------------------------------------------------- /opsweb/auth/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from flask import flash, redirect, url_for, request, current_app 3 | from flask_login import current_user 4 | from functools import wraps 5 | 6 | 7 | def is_cmdb_admin(func): 8 | @wraps(func) 9 | def decorated_function(*args, **kwargs): 10 | if current_user.cmdb_admin == 1: 11 | return func(*args, **kwargs) 12 | else: 13 | flash(current_app.config.get('WEB_ALERT', 'IS_NOT_CMDB_ADMIN'), 'alert') 14 | return redirect(request.referrer) 15 | 16 | return decorated_function 17 | 18 | 19 | def is_zeus_admin(func): 20 | @wraps(func) 21 | def decorated_function(*args, **kwargs): 22 | if current_user.zeus_admin == 1: 23 | return func(*args, **kwargs) 24 | else: 25 | flash(current_app.config.get('WEB_ALERT', 'IS_NOT_ZEUS_ADMIN'), 'alert') 26 | return redirect(request.referrer) 27 | 28 | return decorated_function 29 | 30 | 31 | def is_ad_admin(func): 32 | @wraps(func) 33 | def decorated_function(*args, **kwargs): 34 | if current_user.ad_admin == 1: 35 | return func(*args, **kwargs) 36 | else: 37 | flash(current_app.config.get('WEB_ALERT', 'IS_NOT_AD_ADMIN'), 'alert') 38 | return redirect(request.referrer) 39 | 40 | return decorated_function 41 | -------------------------------------------------------------------------------- /opsweb/auth/crowd.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import crowd 3 | from flask import current_app 4 | """ 5 | 如果username和password在crowd中验证成功,返回dict对象;如果验证失败,返回None; 6 | 增加异常处理,如果建连失败,同样返回None。 7 | """ 8 | 9 | 10 | class Crowd(object): 11 | def __init__(self, username, password): 12 | self.username = username 13 | self.password = password 14 | self.crowd_url = current_app.config['CROWD_URL'] 15 | self.crowd_app = current_app.config['CROWD_APP'] 16 | self.crowd_psw = current_app.config['CROWD_PSW'] 17 | 18 | def auth(self): 19 | try: 20 | crowd_conn = crowd.CrowdServer(self.crowd_url, self.crowd_app, self.crowd_psw) 21 | crowd_auth_result = crowd_conn.auth_user(self.username, self.password) 22 | except Exception as e: 23 | current_app.logger.exception('crowd connection error: '.format(e)) 24 | return None 25 | else: 26 | return crowd_auth_result 27 | -------------------------------------------------------------------------------- /opsweb/auth/login.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from flask import render_template, request, redirect, url_for 3 | from .crowd import * 4 | from .. import login_manager 5 | from ..dao.db_cmdb_user import DBCmdbUser 6 | from flask_login import login_user, login_required, logout_user 7 | from . import auth 8 | 9 | 10 | @login_manager.user_loader 11 | def load_user(user_id): 12 | return DBCmdbUser.query.get(int(user_id)) 13 | 14 | 15 | @auth.route('/login', methods=['GET', 'POST']) 16 | def login(): 17 | error = '' 18 | if request.method == 'POST': 19 | username = request.form['username'] 20 | password = request.form['password'] 21 | crowd_auth = Crowd(username, password).auth() 22 | if crowd_auth is not None: 23 | cmdb_user = DBCmdbUser.query.filter_by(name=username).first() 24 | if cmdb_user is None: 25 | error = current_app.config['USER_LOGIN_PRIVILEGE_ERROR'] 26 | return render_template('login.html', error=error) 27 | login_user(cmdb_user) 28 | next_url = request.args.get('next') 29 | return redirect(next_url or url_for('views.index')) 30 | else: 31 | error = "" 32 | return render_template('login.html', error=error) 33 | 34 | 35 | @auth.route('/logout') 36 | @login_required 37 | def logout(): 38 | logout_user() 39 | return redirect(url_for('auth.login')) 40 | -------------------------------------------------------------------------------- /opsweb/cmdb/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | cmdb = Blueprint('cmdb', __name__) 4 | cmdb_api = Blueprint('cmdb_api', __name__) 5 | 6 | from . import server_physical, server_vps, server_cloudvps, cmdb_user, project, server_privilege, cmdb_api 7 | from . import kvm_privilege, cloud_privilege, server_project, kvm_project, cloud_project, user_project_privilege 8 | -------------------------------------------------------------------------------- /opsweb/cmdb/cloud_privilege.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask import render_template, request, redirect, url_for, flash, Blueprint, current_app 3 | from flask_login import login_required, current_user 4 | from opsweb.auth.admin import is_cmdb_admin 5 | from opsweb.dao.db_cmdb_cloud_user import DBCmdbCloudUser 6 | from opsweb.dao.db_cmdb_cloud_virtual_server import DBCmdbCloudVirtualServer 7 | from opsweb.dao.db_cmdb_user import * 8 | from . import cmdb 9 | 10 | 11 | @cmdb.route('/cloud/privilege/list', methods=['GET']) 12 | @login_required 13 | def cmdb_cloud_privilege_list(): 14 | username = current_user.name 15 | cloud_privileges = DBCmdbCloudUser.query.all() 16 | return render_template('cmdb_cloud_privilege_list.html', cloud_privileges=cloud_privileges) 17 | 18 | 19 | @cmdb.route('/cloud/privilege/add', methods=['GET', 'POST']) 20 | @login_required 21 | @is_cmdb_admin 22 | def cmdb_cloud_privilege_add(): 23 | username = current_user.name 24 | if request.method == 'GET': 25 | servers = DBCmdbCloudVirtualServer.query.all() 26 | cmdb_users = DBCmdbUser.query.all() 27 | return render_template('cmdb_cloud_privilege_add.html', servers=servers, cmdb_users=cmdb_users) 28 | if request.method == 'POST': 29 | try: 30 | server_hostname = request.form['server_hostname'] 31 | email = request.form['email'] 32 | server = DBCmdbCloudVirtualServer.query.filter_by(hostname=server_hostname).first() 33 | cmdb_user = DBCmdbUser.query.filter_by(email=email).first() 34 | server_privilege = DBCmdbCloudUser(server.id, server.hostname, cmdb_user.id, cmdb_user.name, 35 | cmdb_user.cname) 36 | db_cmdb.session.add(server_privilege) 37 | db_cmdb.session.commit() 38 | except Exception as error: 39 | db_cmdb.session.rollback() 40 | flash(current_app.config['DATA_EXIST'], 'alert') 41 | return redirect(request.referrer) 42 | return redirect(url_for("cmdb.cmdb_cloud_privilege_list")) 43 | return None 44 | 45 | 46 | @cmdb.route('/cloud/privilege/del', methods=['GET']) 47 | @login_required 48 | @is_cmdb_admin 49 | def cmdb_cloud_privilege_del(): 50 | username = current_user.name 51 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 52 | 53 | server_privilege = DBCmdbCloudUser.query.filter_by(id=server_privilege_id).first() 54 | db_cmdb.session.delete(server_privilege) 55 | db_cmdb.session.commit() 56 | 57 | return redirect(url_for("cmdb.cmdb_cloud_privilege_list")) 58 | -------------------------------------------------------------------------------- /opsweb/cmdb/cloud_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | from flask import render_template, request, redirect, url_for, flash, current_app 5 | from flask_login import login_required, current_user 6 | 7 | from opsweb.auth.admin import is_cmdb_admin 8 | from opsweb.cmdb import cmdb 9 | from opsweb.dao.db_cmdb_cloud_project import DBCmdbCloudProject 10 | from opsweb.dao.db_cmdb_cloud_virtual_server import DBCmdbCloudVirtualServer 11 | from opsweb.dao.db_cmdb_physics_server_user import DBCmdbPhysicsServerUser 12 | from opsweb.dao.db_cmdb_project import DBCmdbProject 13 | from opsweb.dao.db_cmdb_user import * 14 | 15 | 16 | @cmdb.route('/cloud/project/list', methods=['GET']) 17 | @login_required 18 | def cmdb_cloud_project_list(): 19 | username = current_user.name 20 | server_projects = DBCmdbCloudProject.query.all() 21 | return render_template('cmdb_cloud_project_list.html', server_projects=server_projects) 22 | 23 | 24 | @cmdb.route('/cloud/project/add', methods=['GET', 'POST']) 25 | @login_required 26 | @is_cmdb_admin 27 | def cmdb_cloud_project_add(): 28 | username = current_user.name 29 | if request.method == 'GET': 30 | servers = DBCmdbCloudVirtualServer.query.all() 31 | projects = DBCmdbProject.query.all() 32 | return render_template('cmdb_cloud_project_add.html', servers=servers, projects=projects) 33 | if request.method == 'POST': 34 | try: 35 | server_hostname = request.form['server_hostname'] 36 | project_name = request.form['project_name'] 37 | server = DBCmdbCloudVirtualServer.query.filter_by(hostname=server_hostname).first() 38 | project = DBCmdbProject.query.filter_by(name=project_name).first() 39 | server_privilege = DBCmdbCloudProject(server.id, server.hostname, project.id, project.name) 40 | db_cmdb.session.add(server_privilege) 41 | db_cmdb.session.commit() 42 | except Exception as error: 43 | db_cmdb.session.rollback() 44 | flash(current_app.config.get('DATA_EXIST'), 'alert') 45 | return redirect(request.referrer) 46 | return redirect(url_for("cmdb.cmdb_cloud_project_list")) 47 | return 'You should never reach here' 48 | 49 | 50 | # todo 51 | @cmdb.route('/cloud/project/edit', methods=['GET', 'POST']) 52 | @login_required 53 | def cloud_project_edit(): 54 | username = current_user.name 55 | if request.method == 'GET': 56 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 57 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 58 | return render_template('cmdb_cloud_project_edit.html', server_privilege=server_privilege) 59 | if request.method == 'POST': 60 | server_privilege_id = request.form['serverPrivilegeId'] 61 | server_hostname = request.form['server_hostname'] 62 | cmdb_user_name = request.form['cmdb_user_name'] 63 | server = DBCmdbPhysicsServerUser.query.filter_by(hostname=server_hostname).first() 64 | cmdb_user = DBCmdbUser.query.filter_by(name=cmdb_user_name).first() 65 | 66 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 67 | server_privilege.server_id = server.id 68 | server_privilege.server_hostname = server.hostname 69 | server_privilege.cmdb_user_id = cmdb_user.id 70 | server_privilege.cmdb_user_name = cmdb_user.name 71 | server_privilege.cmdb_user_cname = cmdb_user.cname 72 | db_cmdb.session.commit() 73 | return redirect(url_for("cmdb_cloudvps_project.cmdb_cloud_privilege_list")) 74 | return 'You should never reach here' 75 | 76 | 77 | @cmdb.route('/cloud/project/del', methods=['GET']) 78 | @login_required 79 | @is_cmdb_admin 80 | def cmdb_cloud_project_del(): 81 | username = current_user.name 82 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 83 | 84 | server_privilege = DBCmdbCloudProject.query.filter_by(id=server_privilege_id).first() 85 | db_cmdb.session.delete(server_privilege) 86 | db_cmdb.session.commit() 87 | 88 | return redirect(url_for("cmdb.cmdb_cloud_project_list")) 89 | -------------------------------------------------------------------------------- /opsweb/cmdb/cmdb_apis.py: -------------------------------------------------------------------------------- 1 | # http api CMDB资产管理 权限列表 2 | import json 3 | 4 | # from opsweb.cmdb import cmdb_api 5 | from . import cmdb_api 6 | from opsweb.dao.db_cmdb_cloud_project import DBCmdbCloudProject 7 | from opsweb.dao.db_cmdb_cloud_user import DBCmdbCloudUser 8 | from opsweb.dao.db_cmdb_cloud_virtual_server import DBCmdbCloudVirtualServer 9 | from opsweb.dao.db_cmdb_kvm_project import DBCmdbKvmProject 10 | from opsweb.dao.db_cmdb_kvm_user import DBCmdbKvmUser 11 | from opsweb.dao.db_cmdb_kvm_virtual_server import DBCmdbKVMVirtualServer 12 | from opsweb.dao.db_cmdb_physical_server import DBCmdbPhysicalServer 13 | from opsweb.dao.db_cmdb_physical_server_project import DBCmdbPhysicalServerProject 14 | from opsweb.dao.db_cmdb_physics_server_user import DBCmdbPhysicsServerUser 15 | from opsweb.dao.db_cmdb_project import DBCmdbProject 16 | from opsweb.dao.db_cmdb_user import DBCmdbUser 17 | from opsweb.utils.json_helper import sqlalchemry_ob_to_json 18 | 19 | 20 | @cmdb_api.route('/server/physical', methods=['GET']) 21 | def cmdb_server_physical_list_api(): 22 | try: 23 | servers = DBCmdbPhysicalServer.query.filter_by().all() 24 | except Exception as e: 25 | return json.dumps({'error': 'encode json wrong'}) 26 | return sqlalchemry_ob_to_json(servers) 27 | 28 | 29 | @cmdb_api.route('/server/privilege', methods=['GET']) 30 | def cmdb_server_privilege_list_api(): 31 | try: 32 | servers = DBCmdbPhysicsServerUser.query.filter_by().all() 33 | except Exception as e: 34 | return json.dumps({'error': 'encode json wrong'}) 35 | return sqlalchemry_ob_to_json(servers) 36 | 37 | 38 | @cmdb_api.route('/server/project', methods=['GET']) 39 | def cmdb_server_project_list_api(): 40 | try: 41 | servers = DBCmdbPhysicalServerProject.query.filter_by().all() 42 | except Exception as e: 43 | return json.dumps({'error': 'encode json wrong'}) 44 | return sqlalchemry_ob_to_json(servers) 45 | 46 | 47 | @cmdb_api.route('/vps', methods=['GET']) 48 | def cmdb_server_vps_list_api(): 49 | try: 50 | servers = DBCmdbKVMVirtualServer.query.filter_by().all() 51 | except Exception as e: 52 | return json.dumps({'error': 'encode json wrong'}) 53 | return sqlalchemry_ob_to_json(servers) 54 | 55 | 56 | @cmdb_api.route('/kvm/privilege', methods=['GET']) 57 | def cmdb_kvm_privilege_list_api(): 58 | try: 59 | servers = DBCmdbKvmUser.query.filter_by().all() 60 | except Exception as e: 61 | return json.dumps({'error': 'encode json wrong'}) 62 | return sqlalchemry_ob_to_json(servers) 63 | 64 | 65 | @cmdb_api.route('/kvm/project', methods=['GET']) 66 | def cmdb_kvm_project_list_api(): 67 | try: 68 | servers = DBCmdbKvmProject.query.filter_by().all() 69 | except Exception as e: 70 | return json.dumps({'error': 'encode json wrong'}) 71 | return sqlalchemry_ob_to_json(servers) 72 | 73 | 74 | @cmdb_api.route('/cloud/privilege', methods=['GET']) 75 | def cmdb_cloud_privilege_list_api(): 76 | try: 77 | servers = DBCmdbCloudUser.query.filter_by().all() 78 | except Exception as e: 79 | return json.dumps({'error': 'encode json wrong'}) 80 | return sqlalchemry_ob_to_json(servers) 81 | 82 | 83 | @cmdb_api.route('/server/cloudvps', methods=['GET']) 84 | def cmdb_server_cloudvps_list_api(): 85 | try: 86 | servers = DBCmdbCloudVirtualServer.query.filter_by().all() 87 | except Exception as e: 88 | return json.dumps({'error': 'encode json wrong'}) 89 | return sqlalchemry_ob_to_json(servers) 90 | 91 | 92 | @cmdb_api.route('/cloud/project', methods=['GET']) 93 | def cmdb_cloud_project_list_api(): 94 | try: 95 | servers = DBCmdbCloudProject.query.filter_by().all() 96 | except Exception as e: 97 | return json.dumps({'error': 'encode json wrong'}) 98 | return sqlalchemry_ob_to_json(servers) 99 | 100 | 101 | @cmdb_api.route('/project', methods=['GET']) 102 | def cmdb_api_project(): 103 | try: 104 | projects = DBCmdbProject.query.filter_by().all() 105 | except Exception as e: 106 | return json.dumps({'error': 'encode json wrong'}) 107 | return sqlalchemry_ob_to_json(projects) 108 | 109 | 110 | @cmdb_api.route('/user', methods=['GET']) 111 | def cmdb_user_list_api(): 112 | try: 113 | cmdb_users = DBCmdbUser.query.all() 114 | except Exception as e: 115 | return json.dumps({'error': 'encode json wrong'}) 116 | return sqlalchemry_ob_to_json(cmdb_users) 117 | -------------------------------------------------------------------------------- /opsweb/cmdb/kvm_privilege.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | from flask import render_template, request, redirect, url_for, flash, current_app 5 | from flask_login import login_required, current_user 6 | 7 | from opsweb.auth.admin import is_cmdb_admin 8 | from opsweb.cmdb import cmdb 9 | from opsweb.dao.db_cmdb_kvm_user import DBCmdbKvmUser 10 | from opsweb.dao.db_cmdb_kvm_virtual_server import DBCmdbKVMVirtualServer 11 | from opsweb.dao.db_cmdb_user import * 12 | 13 | 14 | @cmdb.route('/kvm/privilege/list', methods=['GET']) 15 | @login_required 16 | def cmdb_kvm_privilege_list(): 17 | username = current_user.name 18 | kvm_privileges = DBCmdbKvmUser.query.all() 19 | return render_template('cmdb_kvm_privilege_list.html', kvm_privileges=kvm_privileges) 20 | 21 | 22 | @cmdb.route('/kvm/privilege/add', methods=['GET', 'POST']) 23 | @login_required 24 | @is_cmdb_admin 25 | def cmdb_kvm_privilege_add(): 26 | username = current_user.name 27 | if request.method == 'GET': 28 | servers = DBCmdbKVMVirtualServer.query.all() 29 | cmdb_users = DBCmdbUser.query.all() 30 | current_app.logger.info('%s visit cmdb-server-privilege-add page.', username) 31 | return render_template('cmdb_kvm_privilege_add.html', servers=servers, cmdb_users=cmdb_users) 32 | if request.method == 'POST': 33 | try: 34 | server_hostname = request.form['server_hostname'] 35 | email = request.form['email'] 36 | server = DBCmdbKVMVirtualServer.query.filter_by(hostname=server_hostname).first() 37 | cmdb_user = DBCmdbUser.query.filter_by(email=email).first() 38 | server_privilege = DBCmdbKvmUser(server.id, server.hostname, cmdb_user.id, cmdb_user.name, 39 | cmdb_user.cname) 40 | db_cmdb.session.add(server_privilege) 41 | db_cmdb.session.commit() 42 | except Exception as error: 43 | db_cmdb.session.rollback() 44 | flash(current_app.config.get('DATA_EXIST'), 'alert') 45 | return redirect(request.referrer) 46 | return redirect(url_for("cmdb.cmdb_kvm_privilege_list")) 47 | return 'You should never reach here' 48 | 49 | 50 | @cmdb.route('/kvm/privilege/del', methods=['GET']) 51 | @login_required 52 | @is_cmdb_admin 53 | def cmdb_kvm_privilege_del(): 54 | username = current_user.name 55 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 56 | 57 | server_privilege = DBCmdbKvmUser.query.filter_by(id=server_privilege_id).first() 58 | db_cmdb.session.delete(server_privilege) 59 | db_cmdb.session.commit() 60 | 61 | return redirect(url_for("cmdb.cmdb_kvm_privilege_list")) 62 | -------------------------------------------------------------------------------- /opsweb/cmdb/kvm_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | from flask import render_template, request, redirect, url_for, flash, current_app 5 | from flask_login import login_required, current_user 6 | 7 | from opsweb.auth.admin import is_cmdb_admin 8 | from opsweb.cmdb import cmdb 9 | from opsweb.dao.db_cmdb_kvm_project import DBCmdbKvmProject 10 | from opsweb.dao.db_cmdb_kvm_virtual_server import DBCmdbKVMVirtualServer 11 | from opsweb.dao.db_cmdb_physics_server_user import DBCmdbPhysicsServerUser 12 | from opsweb.dao.db_cmdb_project import DBCmdbProject 13 | from opsweb.dao.db_cmdb_user import * 14 | 15 | 16 | @cmdb.route('/kvm/project/list', methods=['GET']) 17 | @login_required 18 | def cmdb_kvm_project_list(): 19 | username = current_user.name 20 | server_projects = DBCmdbKvmProject.query.all() 21 | current_app.logger.info('%s visit cmdb-kvm-privilege-list page.', username) 22 | return render_template('cmdb_kvm_project_list.html', server_projects=server_projects) 23 | 24 | 25 | @cmdb.route('/kvm/project/add', methods=['GET', 'POST']) 26 | @login_required 27 | @is_cmdb_admin 28 | def cmdb_kvm_project_add(): 29 | username = current_user.name 30 | if request.method == 'GET': 31 | servers = DBCmdbKVMVirtualServer.query.all() 32 | projects = DBCmdbProject.query.all() 33 | return render_template('cmdb_kvm_project_add.html', servers=servers, projects=projects) 34 | if request.method == 'POST': 35 | try: 36 | server_hostname = request.form['server_hostname'] 37 | project_name = request.form['project_name'] 38 | server = DBCmdbKVMVirtualServer.query.filter_by(hostname=server_hostname).first() 39 | project = DBCmdbProject.query.filter_by(name=project_name).first() 40 | server_privilege = DBCmdbKvmProject(server.id, server.hostname, project.id, project.name) 41 | db_cmdb.session.add(server_privilege) 42 | db_cmdb.session.commit() 43 | except Exception as error: 44 | db_cmdb.session.rollback() 45 | flash(current_app.config.get('DATA_EXIST'), 'alert') 46 | return redirect(request.referrer) 47 | return redirect(url_for("cmdb.cmdb_kvm_project_list")) 48 | return 'You should never reach here' 49 | 50 | 51 | # todo 52 | @cmdb.route('/kvm/project/edit', methods=['GET', 'POST']) 53 | @login_required 54 | def kvm_project_edit(): 55 | username = current_user.name 56 | if request.method == 'GET': 57 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 58 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 59 | return render_template('cmdb_kvm_project_edit.html', server_privilege=server_privilege) 60 | if request.method == 'POST': 61 | server_privilege_id = request.form['serverPrivilegeId'] 62 | server_hostname = request.form['server_hostname'] 63 | cmdb_user_name = request.form['cmdb_user_name'] 64 | server = DBCmdbPhysicsServerUser.query.filter_by(hostname=server_hostname).first() 65 | cmdb_user = DBCmdbUser.query.filter_by(name=cmdb_user_name).first() 66 | 67 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 68 | server_privilege.server_id = server.id 69 | server_privilege.server_hostname = server.hostname 70 | server_privilege.cmdb_user_id = cmdb_user.id 71 | server_privilege.cmdb_user_name = cmdb_user.name 72 | server_privilege.cmdb_user_cname = cmdb_user.cname 73 | db_cmdb.session.commit() 74 | return redirect(url_for("cmdb.cmdb_kvm_privilege_list")) 75 | return 'You should never reach here' 76 | 77 | 78 | @cmdb.route('/kvm/project/del', methods=['GET']) 79 | @login_required 80 | @is_cmdb_admin 81 | def cmdb_kvm_project_del(): 82 | username = current_user.name 83 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 84 | 85 | server_privilege = DBCmdbKvmProject.query.filter_by(id=server_privilege_id).first() 86 | db_cmdb.session.delete(server_privilege) 87 | db_cmdb.session.commit() 88 | 89 | return redirect(url_for("cmdb.cmdb_kvm_project_list")) 90 | -------------------------------------------------------------------------------- /opsweb/cmdb/project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask import render_template, request, redirect, url_for, Blueprint, current_app 3 | from opsweb import db_cmdb 4 | from flask_login import login_required, current_user 5 | 6 | from opsweb.cmdb import cmdb 7 | from opsweb.dao.db_cmdb_cloud_project import DBCmdbCloudProject 8 | from opsweb.dao.db_cmdb_kvm_project import DBCmdbKvmProject 9 | from opsweb.dao.db_cmdb_physical_server_project import DBCmdbPhysicalServerProject 10 | from opsweb.dao.db_cmdb_project import DBCmdbProject 11 | from opsweb.auth.admin import is_cmdb_admin 12 | import time 13 | 14 | from opsweb.dao.db_cmdb_project_user import DBCmdbProjectUser 15 | 16 | 17 | @cmdb.route('/project/list', methods=['GET']) 18 | @login_required 19 | def cmdb_project_list(): 20 | projects = DBCmdbProject.query.all() 21 | return render_template('cmdb_project_list.html', projects=projects) 22 | 23 | 24 | @cmdb.route('/project/add', methods=['GET', 'POST']) 25 | @login_required 26 | @is_cmdb_admin 27 | def cmdb_project_add(): 28 | if request.method == 'GET': 29 | return render_template('cmdb_project_add.html') 30 | if request.method == 'POST': 31 | name = request.form['name'] 32 | group = request.form['group'] 33 | port = request.form['port'] 34 | port2 = request.form['port2'] 35 | git_source = request.form['git_source'] 36 | remark = request.form['remark'] 37 | create_time = time.strftime('%Y-%m-%d %H:%M:%S') 38 | 39 | project = DBCmdbProject(name, create_time, git_source, group, port, port2, remark) 40 | db_cmdb.session.add(project) 41 | db_cmdb.session.commit() 42 | return redirect(url_for("cmdb.cmdb_project_list")) 43 | return None 44 | 45 | 46 | @cmdb.route('/project/edit', methods=['GET', 'POST']) 47 | @login_required 48 | @is_cmdb_admin 49 | def cmdb_project_edit(): 50 | username = current_user.name 51 | if request.method == 'GET': 52 | project_id = int(request.args.get('projectId', '0')) 53 | project = DBCmdbProject.query.filter_by(id=project_id).first() 54 | current_app.logger.info('%s visit cmdb-project-edit page.', username) 55 | return render_template('cmdb_project_edit.html', project=project) 56 | if request.method == 'POST': 57 | project_id = request.form['projectId'] 58 | name = request.form['name'] 59 | group = request.form['group'] 60 | port = request.form['port'] 61 | remark = request.form['remark'] 62 | 63 | project = DBCmdbProject.query.filter_by(id=project_id).first() 64 | project.name = name 65 | project.group = group 66 | project.port = port 67 | project.remark = remark 68 | db_cmdb.session.commit() 69 | return redirect(url_for("cmdb.cmdb_project_list")) 70 | return 'You should never reach here' 71 | 72 | 73 | @cmdb.route('/project/del', methods=['GET']) 74 | @login_required 75 | @is_cmdb_admin 76 | def cmdb_project_del(): 77 | username = current_user.name 78 | project_id = int(request.args.get('projectId', '0')) 79 | 80 | DBCmdbProject.query.filter_by(id=project_id).delete() 81 | DBCmdbPhysicalServerProject.query.filter_by(project_id=project_id).delete() 82 | DBCmdbKvmProject.query.filter_by(project_id=project_id).delete() 83 | DBCmdbCloudProject.query.filter_by(project_id=project_id).delete() 84 | DBCmdbProjectUser.query.filter_by(project_id=project_id).delete() 85 | db_cmdb.session.commit() 86 | return redirect(url_for("cmdb.cmdb_project_list")) 87 | -------------------------------------------------------------------------------- /opsweb/cmdb/server_privilege.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | from flask import render_template, request, redirect, url_for, flash, current_app 5 | from flask_login import login_required, current_user 6 | 7 | from opsweb.auth.admin import is_cmdb_admin 8 | from opsweb.cmdb import cmdb 9 | from opsweb.dao.db_cmdb_physical_server import DBCmdbPhysicalServer 10 | from opsweb.dao.db_cmdb_physics_server_user import DBCmdbPhysicsServerUser 11 | from opsweb.dao.db_cmdb_user import * 12 | 13 | 14 | @cmdb.route('/server/privilege/list', methods=['GET']) 15 | @login_required 16 | def cmdb_server_privilege_list(): 17 | username = current_user.name 18 | server_privileges = DBCmdbPhysicsServerUser.query.all() 19 | return render_template('cmdb_server_privilege_list.html', server_privileges=server_privileges) 20 | 21 | 22 | @cmdb.route('/server/privilege/add', methods=['GET', 'POST']) 23 | @login_required 24 | @is_cmdb_admin 25 | def cmdb_server_privilege_add(): 26 | username = current_user.name 27 | if request.method == 'GET': 28 | servers = DBCmdbPhysicalServer.query.all() 29 | cmdb_users = DBCmdbUser.query.all() 30 | return render_template('cmdb_server_privilege_add.html', servers=servers, cmdb_users=cmdb_users) 31 | if request.method == 'POST': 32 | try: 33 | server_hostname = request.form['server_hostname'] 34 | email = request.form['email'] 35 | server = DBCmdbPhysicalServer.query.filter_by(hostname=server_hostname).first() 36 | cmdb_user = DBCmdbUser.query.filter_by(email=email).first() 37 | server_privilege = DBCmdbPhysicsServerUser(server.id, server.hostname, cmdb_user.id, cmdb_user.name, 38 | cmdb_user.cname) 39 | db_cmdb.session.add(server_privilege) 40 | db_cmdb.session.commit() 41 | except Exception as error: 42 | db_cmdb.session.rollback() 43 | flash(current_app.config.get('DATA_EXIST'), 'alert') 44 | return redirect(request.referrer) 45 | return redirect(url_for("cmdb.cmdb_server_privilege_list")) 46 | return 'You should never reach here' 47 | 48 | 49 | # todo 50 | @cmdb.route('/server/privilege/edit', methods=['GET', 'POST']) 51 | @login_required 52 | def server_privilege_edit(): 53 | username = current_user.name 54 | if request.method == 'GET': 55 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 56 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 57 | return render_template('cmdb_server_privilege_edit.html', server_privilege=server_privilege) 58 | if request.method == 'POST': 59 | server_privilege_id = request.form['serverPrivilegeId'] 60 | server_hostname = request.form['server_hostname'] 61 | cmdb_user_name = request.form['cmdb_user_name'] 62 | server = DBCmdbPhysicsServerUser.query.filter_by(hostname=server_hostname).first() 63 | cmdb_user = DBCmdbUser.query.filter_by(name=cmdb_user_name).first() 64 | 65 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 66 | server_privilege.server_id = server.id 67 | server_privilege.server_hostname = server.hostname 68 | server_privilege.cmdb_user_id = cmdb_user.id 69 | server_privilege.cmdb_user_name = cmdb_user.name 70 | server_privilege.cmdb_user_cname = cmdb_user.cname 71 | db_cmdb.session.commit() 72 | return redirect(url_for("cmdb.cmdb_server_privilege_list")) 73 | return 'You should never reach here' 74 | 75 | 76 | @cmdb.route('/server/privilege/del', methods=['GET']) 77 | @login_required 78 | @is_cmdb_admin 79 | def cmdb_server_privilege_del(): 80 | username = current_user.name 81 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 82 | 83 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 84 | db_cmdb.session.delete(server_privilege) 85 | db_cmdb.session.commit() 86 | 87 | return redirect(url_for("cmdb.cmdb_server_privilege_list")) 88 | -------------------------------------------------------------------------------- /opsweb/cmdb/server_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import json 3 | 4 | import sqlalchemy 5 | from flask import render_template, request, redirect, url_for, flash, current_app 6 | from flask_login import login_required, current_user 7 | 8 | from opsweb.auth.admin import is_cmdb_admin 9 | from opsweb.cmdb import cmdb 10 | from opsweb.dao.db_cmdb_physical_server import DBCmdbPhysicalServer 11 | from opsweb.dao.db_cmdb_physical_server_project import DBCmdbPhysicalServerProject 12 | from opsweb.dao.db_cmdb_physics_server_user import DBCmdbPhysicsServerUser 13 | from opsweb.dao.db_cmdb_project import DBCmdbProject 14 | from opsweb.dao.db_cmdb_user import * 15 | 16 | 17 | @cmdb.route('/server/project/list', methods=['GET']) 18 | @login_required 19 | def cmdb_server_project_list(): 20 | username = current_user.name 21 | server_projects = DBCmdbPhysicalServerProject.query.all() 22 | return render_template('cmdb_server_project_list.html', server_projects=server_projects) 23 | 24 | 25 | @cmdb.route('/server/project/add', methods=['GET', 'POST']) 26 | @login_required 27 | @is_cmdb_admin 28 | def cmdb_server_project_add(): 29 | username = current_user.name 30 | if request.method == 'GET': 31 | servers = DBCmdbPhysicalServer.query.all() 32 | projects = DBCmdbProject.query.all() 33 | return render_template('cmdb_server_project_add.html', servers=servers, projects=projects) 34 | if request.method == 'POST': 35 | try: 36 | server_hostname = request.form['server_hostname'] 37 | project_name = request.form['project_name'] 38 | server = DBCmdbPhysicalServer.query.filter_by(hostname=server_hostname).first() 39 | project = DBCmdbProject.query.filter_by(name=project_name).first() 40 | server_privilege = DBCmdbPhysicalServerProject(server.id, server.hostname, project.id, project.name) 41 | db_cmdb.session.add(server_privilege) 42 | db_cmdb.session.commit() 43 | except Exception as error: 44 | db_cmdb.session.rollback() 45 | flash(current_app.config.get('DATA_EXIST'), 'alert') 46 | return redirect(request.referrer) 47 | return redirect(url_for("cmdb.cmdb_server_project_list")) 48 | return 'You should never reach here' 49 | 50 | 51 | @cmdb.route('/server/project/edit', methods=['GET', 'POST']) 52 | @login_required 53 | def server_project_edit(): 54 | username = current_user.name 55 | if request.method == 'GET': 56 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 57 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 58 | return render_template('cmdb_server_project_edit.html', server_privilege=server_privilege) 59 | if request.method == 'POST': 60 | server_privilege_id = request.form['serverPrivilegeId'] 61 | server_hostname = request.form['server_hostname'] 62 | cmdb_user_name = request.form['cmdb_user_name'] 63 | server = DBCmdbPhysicsServerUser.query.filter_by(hostname=server_hostname).first() 64 | cmdb_user = DBCmdbUser.query.filter_by(name=cmdb_user_name).first() 65 | 66 | server_privilege = DBCmdbPhysicsServerUser.query.filter_by(id=server_privilege_id).first() 67 | server_privilege.server_id = server.id 68 | server_privilege.server_hostname = server.hostname 69 | server_privilege.cmdb_user_id = cmdb_user.id 70 | server_privilege.cmdb_user_name = cmdb_user.name 71 | server_privilege.cmdb_user_cname = cmdb_user.cname 72 | db_cmdb.session.commit() 73 | return redirect(url_for("cmdb.cmdb_project_privilege_list")) 74 | return 'You should never reach here' 75 | 76 | 77 | @cmdb.route('/server/project/del', methods=['GET']) 78 | @login_required 79 | @is_cmdb_admin 80 | def cmdb_server_project_del(): 81 | username = current_user.name 82 | server_privilege_id = int(request.args.get('serverPrivilegeId', '0')) 83 | 84 | server_privilege = DBCmdbPhysicalServerProject.query.filter_by(id=server_privilege_id).first() 85 | db_cmdb.session.delete(server_privilege) 86 | db_cmdb.session.commit() 87 | 88 | return redirect(url_for("cmdb.cmdb_server_project_list")) 89 | -------------------------------------------------------------------------------- /opsweb/cmdb/user_project_privilege.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from flask import render_template, url_for, redirect, flash, request, Blueprint 3 | from flask_login import login_required, current_user 4 | 5 | from opsweb.cmdb import cmdb 6 | from opsweb.utils.user_zeus_privilege import * 7 | from opsweb.dao.db_zeus_project import * 8 | from opsweb.utils.check_privilege import * 9 | 10 | 11 | @cmdb.route('/user/privilege/list', methods=['GET']) 12 | @login_required 13 | @check_zeus_admin 14 | def zeus_user_privilege(): 15 | project_users = DBCmdbProjectUser.query.all() 16 | projects = DBZeusProject.query.all() 17 | users = DBCmdbUser.query.all() 18 | 19 | return render_template('zeus_user_privilege.html', project_users=project_users, projects=projects, users=users) 20 | 21 | 22 | @cmdb.route('/user/privilege/add', methods=['POST']) 23 | @login_required 24 | @check_zeus_admin 25 | def admin_user_privilege_add(): 26 | email = request.form['email'] 27 | project_name = request.form['projectName'] 28 | 29 | user = DBCmdbUser.query.filter_by(email=email).first() 30 | project = DBZeusProject.query.filter_by(name=project_name).first() 31 | # TODO:增加project为空的判断 32 | try: 33 | user_privilege = DBCmdbProjectUser(project.id, project.name, user.id, user.name, user.cname) 34 | db_cmdb.session.add(user_privilege) 35 | db_cmdb.session.commit() 36 | except Exception as e: 37 | db_cmdb.session.rollback() 38 | flash(current_app.config['DATA_EXIST'], 'alert') 39 | return redirect(request.referrer) 40 | return redirect(url_for("cmdb.zeus_user_privilege")) 41 | 42 | 43 | # todo 删除编辑按钮 44 | @cmdb.route('/user/privilege/edit', methods=['GET', 'POST']) 45 | @login_required 46 | @check_zeus_admin 47 | def zeus_user_privilege_edit(): 48 | if request.method == 'GET': 49 | user_privilege_id = int(request.args.get('id', '0')) 50 | user_privilege = DBCmdbProjectUser.query.filter_by(id=user_privilege_id).first() 51 | return render_template('zeus_user_privilege_edit.html', user_privilege=user_privilege) 52 | 53 | if request.method == 'POST': 54 | user_privilege_id = int(request.form['id']) 55 | user_id = request.form['userId'] 56 | project_id = request.form['userId'] 57 | 58 | user_info = DBCmdbUser.query.filter_by(id=user_id).first() 59 | project = DBZeusProject.query.filter_by(id=project_id).first() 60 | user_privilege = DBCmdbProjectUser.query.filter_by(id=user_privilege_id).first() 61 | user_privilege.user_id = user_info.id 62 | user_privilege.project_id = project.id 63 | user_privilege.project_name = project.project_name 64 | db_cmdb.session.commit() 65 | return redirect(url_for("cmdb.zeus_user_privilege")) 66 | 67 | return "Error method." 68 | 69 | 70 | @cmdb.route('/user/privilege/del', methods=['GET']) 71 | @login_required 72 | @check_zeus_admin 73 | def zeus_user_privilege_del(): 74 | user_privilege_id = int(request.args.get('id', '0')) 75 | user_privilege = DBCmdbProjectUser.query.filter_by(id=user_privilege_id).first() 76 | db_cmdb.session.delete(user_privilege) 77 | db_cmdb.session.commit() 78 | return redirect(url_for("cmdb.zeus_user_privilege")) 79 | -------------------------------------------------------------------------------- /opsweb/dao/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/dao/__init__.py -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_ad_user.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbADUser(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'ad_user' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | name = db_cmdb.Column(db_cmdb.String(255)) 10 | initial_pwd = db_cmdb.Column(db_cmdb.String(255)) 11 | 12 | def __init__(self, name, initial_pwd): 13 | self.name = name 14 | self.initial_pwd = initial_pwd 15 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_cloud_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbCloudProject(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'cloud_vs_project' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | cloud_vs_id = db_cmdb.Column(db_cmdb.Integer) 10 | cloud_vs_hostname = db_cmdb.Column(db_cmdb.String(255)) 11 | project_id = db_cmdb.Column(db_cmdb.Integer) 12 | project_name = db_cmdb.Column(db_cmdb.String(255)) 13 | 14 | def __init__(self, cloud_vs_id, cloud_vs_hostname, project_id, project_name): 15 | self.cloud_vs_id = cloud_vs_id 16 | self.cloud_vs_hostname = cloud_vs_hostname 17 | self.project_id = project_id 18 | self.project_name = project_name 19 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_cloud_user.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbCloudUser(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'cloud_vs_cmdb_user' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | cloud_vs_id = db_cmdb.Column(db_cmdb.Integer) 10 | cloud_vs_hostname = db_cmdb.Column(db_cmdb.String(255)) 11 | cmdb_user_id = db_cmdb.Column(db_cmdb.Integer) 12 | cmdb_user_name = db_cmdb.Column(db_cmdb.String(255)) 13 | cmdb_user_cname = db_cmdb.Column(db_cmdb.String(255)) 14 | 15 | def __init__(self, cloud_vs_id, cloud_vs_hostname, cmdb_user_id, cmdb_user_name, cmdb_user_cname): 16 | self.cloud_vs_id = cloud_vs_id 17 | self.cloud_vs_hostname = cloud_vs_hostname 18 | self.cmdb_user_id = cmdb_user_id 19 | self.cmdb_user_name = cmdb_user_name 20 | self.cmdb_user_cname = cmdb_user_cname 21 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_cloud_virtual_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbCloudVirtualServer(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'cloud_virtual_server' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | hostname = db_cmdb.Column(db_cmdb.String(255), index=True) 10 | create_time = db_cmdb.Column(db_cmdb.DateTime) 11 | cpu = db_cmdb.Column(db_cmdb.Integer) 12 | memory = db_cmdb.Column(db_cmdb.Integer) 13 | disk = db_cmdb.Column(db_cmdb.Integer) 14 | wanip = db_cmdb.Column(db_cmdb.String(255)) 15 | wanip_alternate = db_cmdb.Column(db_cmdb.String(255)) 16 | broadband_type = db_cmdb.Column(db_cmdb.String(255)) 17 | lanip = db_cmdb.Column(db_cmdb.String(255)) 18 | os = db_cmdb.Column(db_cmdb.String(255)) 19 | os_version = db_cmdb.Column(db_cmdb.String(255)) 20 | location = db_cmdb.Column(db_cmdb.String(255)) 21 | group = db_cmdb.Column(db_cmdb.String(255)) 22 | remark = db_cmdb.Column(db_cmdb.String(255)) 23 | 24 | def __init__(self, hostname, create_time, cpu, memory, disk, wanip, wanip_alternate, broadband_type, lanip, os, 25 | os_version, location, group, remark): 26 | self.hostname = hostname 27 | self.create_time = create_time 28 | self.cpu = cpu 29 | self.memory = memory 30 | self.disk = disk 31 | self.wanip = wanip 32 | self.wanip_alternate = wanip_alternate 33 | self.broadband_type = broadband_type 34 | self.lanip = lanip 35 | self.os = os 36 | self.os_version = os_version 37 | self.location = location 38 | self.group = group 39 | self.remark = remark 40 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_kvm_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbKvmProject(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'kvm_vs_project' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | kvm_vs_id = db_cmdb.Column(db_cmdb.Integer) 10 | kvm_vs_hostname = db_cmdb.Column(db_cmdb.String(255)) 11 | project_id = db_cmdb.Column(db_cmdb.Integer) 12 | project_name = db_cmdb.Column(db_cmdb.String(255)) 13 | 14 | def __init__(self, kvm_vs_id, kvm_vs_hostname, project_id, project_name): 15 | self.kvm_vs_id = kvm_vs_id 16 | self.kvm_vs_hostname = kvm_vs_hostname 17 | self.project_id = project_id 18 | self.project_name = project_name 19 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_kvm_user.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbKvmUser(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'kvm_vs_cmdb_user' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | kvm_vs_id = db_cmdb.Column(db_cmdb.Integer) 10 | kvm_vs_hostname = db_cmdb.Column(db_cmdb.String(255)) 11 | cmdb_user_id = db_cmdb.Column(db_cmdb.Integer) 12 | cmdb_user_name = db_cmdb.Column(db_cmdb.String(255)) 13 | cmdb_user_cname = db_cmdb.Column(db_cmdb.String(255)) 14 | 15 | def __init__(self, kvm_vs_id, kvm_vs_hostname, cmdb_user_id, cmdb_user_name, cmdb_user_cname): 16 | self.kvm_vs_id = kvm_vs_id 17 | self.kvm_vs_hostname = kvm_vs_hostname 18 | self.cmdb_user_id = cmdb_user_id 19 | self.cmdb_user_name = cmdb_user_name 20 | self.cmdb_user_cname = cmdb_user_cname 21 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_kvm_virtual_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbKVMVirtualServer(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'kvm_virtual_server' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | hostname = db_cmdb.Column(db_cmdb.String(255), index=True) 10 | create_time = db_cmdb.Column(db_cmdb.DateTime) 11 | cpu = db_cmdb.Column(db_cmdb.Integer) 12 | memory = db_cmdb.Column(db_cmdb.Integer) 13 | disk = db_cmdb.Column(db_cmdb.Integer) 14 | wanip = db_cmdb.Column(db_cmdb.String(255)) 15 | wanip_alternate = db_cmdb.Column(db_cmdb.String(255)) 16 | broadband_type = db_cmdb.Column(db_cmdb.String(255)) 17 | lanip = db_cmdb.Column(db_cmdb.String(255)) 18 | os = db_cmdb.Column(db_cmdb.String(255)) 19 | os_version = db_cmdb.Column(db_cmdb.String(255)) 20 | kvm_host = db_cmdb.Column(db_cmdb.String(255)) 21 | kvm_cpu_bind = db_cmdb.Column(db_cmdb.String(255)) 22 | kvm_vnc_ip = db_cmdb.Column(db_cmdb.String(255)) 23 | kvm_vnc_port = db_cmdb.Column(db_cmdb.Integer) 24 | location = db_cmdb.Column(db_cmdb.String(255)) 25 | group = db_cmdb.Column(db_cmdb.String(255)) 26 | remark = db_cmdb.Column(db_cmdb.String(255)) 27 | 28 | def __init__(self, hostname, create_time, cpu, memory, disk, wanip, wanip_alternate, broadband_type, lanip, os, 29 | os_version, kvm_host, kvm_cpu_bind, kvm_vnc_ip, kvm_vnc_port, location, group, remark): 30 | self.hostname = hostname 31 | self.create_time = create_time 32 | self.cpu = cpu 33 | self.memory = memory 34 | self.disk = disk 35 | self.wanip = wanip 36 | self.wanip_alternate = wanip_alternate 37 | self.broadband_type = broadband_type 38 | self.lanip = lanip 39 | self.os = os 40 | self.os_version = os_version 41 | self.kvm_host = kvm_host 42 | self.kvm_cpu_bind = kvm_cpu_bind 43 | self.kvm_vnc_ip = kvm_vnc_ip 44 | self.kvm_vnc_port = kvm_vnc_port 45 | self.location = location 46 | self.group = group 47 | self.remark = remark 48 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_lanip.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class LanIP(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'lanip' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | ip = db_cmdb.Column(db_cmdb.String(255), index=True) 10 | buy_time = db_cmdb.Column(db_cmdb.DateTime) 11 | mask = db_cmdb.Column(db_cmdb.String(255)) 12 | gateway = db_cmdb.Column(db_cmdb.String(255)) 13 | ip_range = db_cmdb.Column(db_cmdb.String(255)) 14 | used = db_cmdb.Column(db_cmdb.Integer) 15 | hostname = db_cmdb.Column(db_cmdb.String(255)) 16 | remark = db_cmdb.Column(db_cmdb.String(255)) 17 | 18 | def __init__(self, ip, buy_time, mask, gateway, ip_range, used, hostname, remark): 19 | self.ip = ip 20 | self.buy_time = buy_time 21 | self.mask = mask 22 | self.gateway = gateway 23 | self.ip_range = ip_range 24 | self.used = used 25 | self.hostname = hostname 26 | self.remark = remark 27 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_physical_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbPhysicalServer(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'physical_server' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | hostname = db_cmdb.Column(db_cmdb.String(255), index=True) 10 | buy_time = db_cmdb.Column(db_cmdb.DateTime) 11 | create_time = db_cmdb.Column(db_cmdb.DateTime) 12 | company = db_cmdb.Column(db_cmdb.String(255)) 13 | service_no = db_cmdb.Column(db_cmdb.String(255)) 14 | cpu = db_cmdb.Column(db_cmdb.Integer) 15 | cpu_physical_num = db_cmdb.Column(db_cmdb.Integer) 16 | cpu_details = db_cmdb.Column(db_cmdb.String(255)) 17 | memory = db_cmdb.Column(db_cmdb.Integer) 18 | memory_physical_num = db_cmdb.Column(db_cmdb.Integer) 19 | memory_details = db_cmdb.Column(db_cmdb.String(255)) 20 | disk = db_cmdb.Column(db_cmdb.Integer) 21 | disk_physical_num = db_cmdb.Column(db_cmdb.Integer) 22 | disk_details = db_cmdb.Column(db_cmdb.String(255)) 23 | raid_level = db_cmdb.Column(db_cmdb.Integer) 24 | raid_details = db_cmdb.Column(db_cmdb.String(255)) 25 | power_physical_num = db_cmdb.Column(db_cmdb.Integer) 26 | power_details = db_cmdb.Column(db_cmdb.String(255)) 27 | nic_physical_num = db_cmdb.Column(db_cmdb.Integer) 28 | nic_details = db_cmdb.Column(db_cmdb.String(255)) 29 | idrac = db_cmdb.Column(db_cmdb.String(255)) 30 | wanip = db_cmdb.Column(db_cmdb.String(255)) 31 | wanip_alternate = db_cmdb.Column(db_cmdb.String(255)) 32 | broadband_type = db_cmdb.Column(db_cmdb.String(255)) 33 | lanip = db_cmdb.Column(db_cmdb.String(255)) 34 | manageip = db_cmdb.Column(db_cmdb.String(255)) 35 | os = db_cmdb.Column(db_cmdb.String(255)) 36 | os_version = db_cmdb.Column(db_cmdb.String(255)) 37 | location = db_cmdb.Column(db_cmdb.String(255)) 38 | group = db_cmdb.Column(db_cmdb.String(255)) 39 | remark = db_cmdb.Column(db_cmdb.String(255)) 40 | 41 | def __init__(self, hostname, buy_time, create_time, company, service_no, cpu, cpu_physical_num, cpu_details, memory, 42 | memory_physical_num, memory_details, disk, disk_physical_num, disk_details, raid_level, raid_details, 43 | power_physical_num, power_details, nic_physical_num, nic_details, idrac, wanip, wanip_alternate, 44 | broadband_type, lanip, manageip, os, os_version, location, group, remark): 45 | self.hostname = hostname 46 | self.buy_time = buy_time 47 | self.create_time = create_time 48 | self.company = company 49 | self.service_no = service_no 50 | self.cpu = cpu 51 | self.cpu_physical_num = cpu_physical_num 52 | self.cpu_details = cpu_details 53 | self.memory = memory 54 | self.memory_physical_num = memory_physical_num 55 | self.memory_details = memory_details 56 | self.disk = disk 57 | self.disk_physical_num = disk_physical_num 58 | self.disk_details = disk_details 59 | self.raid_level = raid_level 60 | self.raid_details = raid_details 61 | self.power_physical_num = power_physical_num 62 | self.power_details = power_details 63 | self.nic_physical_num = nic_physical_num 64 | self.nic_details = nic_details 65 | self.idrac = idrac 66 | self.wanip = wanip 67 | self.wanip_alternate = wanip_alternate 68 | self.broadband_type = broadband_type 69 | self.lanip = lanip 70 | self.manageip = manageip 71 | self.os = os 72 | self.os_version = os_version 73 | self.location = location 74 | self.group = group 75 | self.remark = remark 76 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_physical_server_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbPhysicalServerProject(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'physical_server_project' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | physical_server_id = db_cmdb.Column(db_cmdb.Integer) 10 | physical_server_hostname = db_cmdb.Column(db_cmdb.String(255)) 11 | project_id = db_cmdb.Column(db_cmdb.Integer) 12 | project_name = db_cmdb.Column(db_cmdb.String(255)) 13 | 14 | def __init__(self, physical_server_id, physical_server_hostname, project_id, project_name): 15 | self.physical_server_id = physical_server_id 16 | self.physical_server_hostname = physical_server_hostname 17 | self.project_id = project_id 18 | self.project_name = project_name 19 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_physics_server_user.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbPhysicsServerUser(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'physical_server_cmdb_user' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | physical_server_id = db_cmdb.Column(db_cmdb.Integer) 10 | physical_server_hostname = db_cmdb.Column(db_cmdb.String(255)) 11 | cmdb_user_id = db_cmdb.Column(db_cmdb.Integer) 12 | cmdb_user_name = db_cmdb.Column(db_cmdb.String(255)) 13 | cmdb_user_cname = db_cmdb.Column(db_cmdb.String(255)) 14 | 15 | def __init__(self, physical_server_id, physical_server_hostname, cmdb_user_id, cmdb_user_name, cmdb_user_cname): 16 | self.physical_server_id = physical_server_id 17 | self.physical_server_hostname = physical_server_hostname 18 | self.cmdb_user_id = cmdb_user_id 19 | self.cmdb_user_name = cmdb_user_name 20 | self.cmdb_user_cname = cmdb_user_cname 21 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbProject(db_cmdb.Model): 6 | extend_existing = True 7 | __bind_key__ = 'cmdb' 8 | __tablename__ = 'project' 9 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 10 | name = db_cmdb.Column(db_cmdb.String(255), index=True) 11 | create_time = db_cmdb.Column(db_cmdb.DateTime) 12 | git_source = db_cmdb.Column(db_cmdb.String(255)) 13 | group = db_cmdb.Column(db_cmdb.String(255)) 14 | port = db_cmdb.Column(db_cmdb.Integer) 15 | port2 = db_cmdb.Column(db_cmdb.Integer) 16 | remark = db_cmdb.Column(db_cmdb.String(255)) 17 | 18 | def __init__(self, name, create_time, git_source, group, port, port2, remark): 19 | self.name = name 20 | self.create_time = create_time 21 | self.git_source = git_source 22 | self.group = group 23 | self.port = port 24 | self.port2 = port2 25 | self.remark = remark 26 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_project_user.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class DBCmdbProjectUser(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'project_cmdb_user' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | project_id = db_cmdb.Column(db_cmdb.Integer) 10 | project_name = db_cmdb.Column(db_cmdb.String(255)) 11 | cmdb_user_id = db_cmdb.Column(db_cmdb.Integer) 12 | cmdb_user_name = db_cmdb.Column(db_cmdb.String(255)) 13 | cmdb_user_cname = db_cmdb.Column(db_cmdb.String(255)) 14 | 15 | def __init__(self, project_id, project_name, cmdb_user_id, cmdb_user_name, cmdb_user_cname): 16 | self.project_id = project_id 17 | self.project_name = project_name 18 | self.cmdb_user_id = cmdb_user_id 19 | self.cmdb_user_name = cmdb_user_name 20 | self.cmdb_user_cname = cmdb_user_cname 21 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_user.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask_login import UserMixin 3 | from .. import db_cmdb 4 | 5 | 6 | class DBCmdbUser(db_cmdb.Model, UserMixin): 7 | __bind_key__ = 'cmdb' 8 | __tablename__ = 'cmdb_user' 9 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 10 | name = db_cmdb.Column(db_cmdb.String(255)) 11 | create_time = db_cmdb.Column(db_cmdb.DateTime) 12 | realname = db_cmdb.Column(db_cmdb.String(255)) 13 | cname = db_cmdb.Column(db_cmdb.String(255), index=True) 14 | email = db_cmdb.Column(db_cmdb.String(1024)) 15 | phone = db_cmdb.Column(db_cmdb.String(255)) 16 | ad_admin = db_cmdb.Column(db_cmdb.Integer) 17 | zeus_admin = db_cmdb.Column(db_cmdb.Integer) 18 | cmdb_admin = db_cmdb.Column(db_cmdb.Integer) 19 | remark = db_cmdb.Column(db_cmdb.String(255)) 20 | 21 | def __init__(self, name, create_time, realname, cname, email, phone, ad_admin, zeus_admin, cmdb_admin, remark): 22 | self.name = name 23 | self.create_time = create_time 24 | self.realname = realname 25 | self.cname = cname 26 | self.email = email 27 | self.phone = phone 28 | self.ad_admin = ad_admin 29 | self.zeus_admin = zeus_admin 30 | self.cmdb_admin = cmdb_admin 31 | self.remark = remark 32 | -------------------------------------------------------------------------------- /opsweb/dao/db_cmdb_wanip.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_cmdb 3 | 4 | 5 | class WanIP(db_cmdb.Model): 6 | __bind_key__ = 'cmdb' 7 | __tablename__ = 'wanip' 8 | id = db_cmdb.Column(db_cmdb.Integer, primary_key=True, autoincrement=True) 9 | ip = db_cmdb.Column(db_cmdb.String(255), index=True) 10 | broadband_type = db_cmdb.Column(db_cmdb.String(255)) 11 | buy_time = db_cmdb.Column(db_cmdb.DateTime) 12 | mask = db_cmdb.Column(db_cmdb.String(255)) 13 | gateway = db_cmdb.Column(db_cmdb.String(255)) 14 | ip_range = db_cmdb.Column(db_cmdb.String(255)) 15 | used = db_cmdb.Column(db_cmdb.Integer) 16 | hostname = db_cmdb.Column(db_cmdb.String(255)) 17 | remark = db_cmdb.Column(db_cmdb.String(255)) 18 | 19 | def __init__(self, ip, broadband_type, buy_time, mask, gateway, ip_range, used, hostname, remark): 20 | self.ip = ip 21 | self.broadband_type = broadband_type 22 | self.hostname = hostname 23 | self.buy_time = buy_time 24 | self.mask = mask 25 | self.gateway = gateway 26 | self.ip_range = ip_range 27 | self.used = used 28 | self.hostname = hostname 29 | self.remark = remark 30 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_project.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusProject(db_zeus.Model): 6 | extend_existing = True 7 | __bind_key__ = 'zeus' 8 | __tablename__ = 'project' 9 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 10 | name = db_zeus.Column(db_zeus.String(255)) 11 | cname = db_zeus.Column(db_zeus.String(255)) 12 | source = db_zeus.Column(db_zeus.String(1024)) 13 | parent_project = db_zeus.Column(db_zeus.String(255)) 14 | build_type = db_zeus.Column(db_zeus.String(255)) 15 | startup_type = db_zeus.Column(db_zeus.String(255)) 16 | create_time = db_zeus.Column(db_zeus.DateTime) 17 | 18 | def __init__(self, name, cname, source, parent_project, build_type, startup_type, create_time): 19 | self.name = name 20 | self.cname = cname 21 | self.source = source 22 | self.parent_project = parent_project 23 | self.build_type = build_type 24 | self.startup_type = startup_type 25 | self.create_time = create_time 26 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_project_build.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusProjectBuild(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'project_build' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True) 9 | project_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project.id')) 10 | branch = db_zeus.Column(db_zeus.String(255)) 11 | build_done = db_zeus.Column(db_zeus.Integer) 12 | build_log = db_zeus.Column(db_zeus.Text) 13 | create_time = db_zeus.Column(db_zeus.DateTime) 14 | 15 | def __init__(self, build_id, project_id, branch, build_done, build_log, create_time): 16 | self.id = build_id 17 | self.project_id = project_id 18 | self.branch = branch 19 | self.build_done = build_done 20 | self.build_log = build_log 21 | self.create_time = create_time 22 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_project_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusProjectConfig(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'project_config' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 9 | project_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project.id')) 10 | env = db_zeus.Column(db_zeus.String(255)) 11 | path = db_zeus.Column(db_zeus.String(255)) 12 | filename = db_zeus.Column(db_zeus.String(255)) 13 | content = db_zeus.Column(db_zeus.Text) 14 | 15 | def __init__(self, project_id, env, path, filename, content): 16 | self.project_id = project_id 17 | self.env = env 18 | self.path = path 19 | self.filename = filename 20 | self.content = content 21 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_project_deploy_job.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusProjectDeployJob(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'project_deploy_job' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 9 | project_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project.id')) 10 | project_build_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project_build.id')) 11 | task_num = db_zeus.Column(db_zeus.Integer) 12 | create_time = db_zeus.Column(db_zeus.DateTime) 13 | 14 | def __init__(self, job_id, project_id, project_build_id, task_num, create_time): 15 | self.id = job_id 16 | self.project_id = project_id 17 | self.project_build_id = project_build_id 18 | self.task_num = task_num 19 | self.create_time = create_time 20 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_project_deploy_task.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusProjectDeployTask(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'project_deploy_task' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 9 | job_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project_deploy_job.id')) 10 | project_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project.id')) 11 | project_build_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project_build.id')) 12 | env = db_zeus.Column(db_zeus.String(255)) 13 | server_ip = db_zeus.Column(db_zeus.String(255)) 14 | path = db_zeus.Column(db_zeus.String(255)) 15 | deploy_done = db_zeus.Column(db_zeus.Integer) 16 | deploy_log = db_zeus.Column(db_zeus.Text) 17 | 18 | def __init__(self, job_id, project_id, project_build_id, env, server_ip, path, deploy_done, deploy_log): 19 | self.job_id = job_id 20 | self.project_id = project_id 21 | self.project_build_id = project_build_id 22 | self.env = env 23 | self.server_ip = server_ip 24 | self.path = path 25 | self.deploy_done = deploy_done 26 | self.deploy_log = deploy_log 27 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_project_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusProjectServer(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'project_server' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 9 | project_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project.id')) 10 | env = db_zeus.Column(db_zeus.String(255)) 11 | server_ip = db_zeus.Column(db_zeus.String(255)) 12 | path = db_zeus.Column(db_zeus.String(255)) 13 | 14 | def __init__(self, project_id, env, server_ip, path): 15 | self.project_id = project_id 16 | self.env = env 17 | self.server_ip = server_ip 18 | self.path = path 19 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_user_info.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusUserInfo(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'user_info' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 9 | username = db_zeus.Column(db_zeus.String(255)) 10 | role = db_zeus.Column(db_zeus.String(255)) 11 | 12 | def __init__(self, username, role): 13 | self.username = username 14 | self.role = role 15 | -------------------------------------------------------------------------------- /opsweb/dao/db_zeus_user_privilege.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from opsweb import db_zeus 3 | 4 | 5 | class DBZeusUserPrivilege(db_zeus.Model): 6 | __bind_key__ = 'zeus' 7 | __tablename__ = 'user_privilege' 8 | id = db_zeus.Column(db_zeus.Integer, primary_key=True, autoincrement=True) 9 | user_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('user_info.id')) 10 | project_id = db_zeus.Column(db_zeus.Integer, db_zeus.ForeignKey('project.id')) 11 | project_name = db_zeus.Column(db_zeus.String(255)) 12 | 13 | def __init__(self, user_id, project_id, project_name): 14 | self.user_id = user_id 15 | self.project_id = project_id 16 | self.project_name = project_name 17 | -------------------------------------------------------------------------------- /opsweb/static/css/custom.css: -------------------------------------------------------------------------------- 1 | label { 2 | width: 440px; 3 | display: inline-block; 4 | max-width: 300%; 5 | margin-bottom: 5px; 6 | font-weight: 700; 7 | } 8 | 9 | .edit, .del { 10 | width: 20px; 11 | text-align: right; 12 | color: red; 13 | font-weight:bold; 14 | } 15 | 16 | .table-condensed>thead>tr>th, .table-condensed>tbody>tr>th, .table-condensed>tfoot>tr>th, .table-condensed>thead>tr>td, .table-condensed>tbody>tr>td, .table-condensed>tfoot>tr>td{ 17 | padding-top: 8px; 18 | padding-right: 5px; 19 | padding-bottom: 8px; 20 | padding-left: 5px; 21 | } 22 | .modal-list li { 23 | margin-bottom:10px; 24 | margin-top:10px; 25 | } 26 | 27 | .modal-list li div { 28 | margin-bottom:10px; 29 | } 30 | 31 | .col-lg-12 { 32 | position: relative; 33 | } 34 | 35 | .loading { 36 | width: 100%; 37 | background: #fff; 38 | height: 100%; 39 | position: absolute; 40 | z-index: 10; 41 | top: 0; 42 | left: 0; 43 | } 44 | -------------------------------------------------------------------------------- /opsweb/static/css/dataTables.responsive.css: -------------------------------------------------------------------------------- 1 | table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child, 2 | table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child { 3 | position: relative; 4 | padding-left: 30px; 5 | cursor: pointer; 6 | } 7 | table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before, 8 | table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before { 9 | top: 8px; 10 | left: 4px; 11 | height: 16px; 12 | width: 16px; 13 | display: block; 14 | position: absolute; 15 | color: white; 16 | border: 2px solid white; 17 | border-radius: 16px; 18 | text-align: center; 19 | line-height: 14px; 20 | box-shadow: 0 0 3px #444; 21 | box-sizing: content-box; 22 | content: '+'; 23 | background-color: #31b131; 24 | } 25 | table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child.dataTables_empty:before, 26 | table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child.dataTables_empty:before { 27 | display: none; 28 | } 29 | table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before, 30 | table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before { 31 | content: '-'; 32 | background-color: #d33333; 33 | } 34 | table.dataTable.dtr-inline.collapsed > tbody > tr.child td:before { 35 | display: none; 36 | } 37 | table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child, 38 | table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child { 39 | padding-left: 27px; 40 | } 41 | table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before, 42 | table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before { 43 | top: 5px; 44 | left: 4px; 45 | height: 14px; 46 | width: 14px; 47 | border-radius: 14px; 48 | line-height: 12px; 49 | } 50 | table.dataTable.dtr-column > tbody > tr > td.control, 51 | table.dataTable.dtr-column > tbody > tr > th.control { 52 | position: relative; 53 | cursor: pointer; 54 | } 55 | table.dataTable.dtr-column > tbody > tr > td.control:before, 56 | table.dataTable.dtr-column > tbody > tr > th.control:before { 57 | top: 50%; 58 | left: 50%; 59 | height: 16px; 60 | width: 16px; 61 | margin-top: -10px; 62 | margin-left: -10px; 63 | display: block; 64 | position: absolute; 65 | color: white; 66 | border: 2px solid white; 67 | border-radius: 16px; 68 | text-align: center; 69 | line-height: 14px; 70 | box-shadow: 0 0 3px #444; 71 | box-sizing: content-box; 72 | content: '+'; 73 | background-color: #31b131; 74 | } 75 | table.dataTable.dtr-column > tbody > tr.parent td.control:before, 76 | table.dataTable.dtr-column > tbody > tr.parent th.control:before { 77 | content: '-'; 78 | background-color: #d33333; 79 | } 80 | table.dataTable > tbody > tr.child { 81 | padding: 0.5em 1em; 82 | } 83 | table.dataTable > tbody > tr.child:hover { 84 | background: transparent !important; 85 | } 86 | table.dataTable > tbody > tr.child ul { 87 | display: inline-block; 88 | list-style-type: none; 89 | margin: 0; 90 | padding: 0; 91 | } 92 | table.dataTable > tbody > tr.child ul li { 93 | border-bottom: 1px solid #efefef; 94 | padding: 0.5em 0; 95 | } 96 | table.dataTable > tbody > tr.child ul li:first-child { 97 | padding-top: 0; 98 | } 99 | table.dataTable > tbody > tr.child ul li:last-child { 100 | border-bottom: none; 101 | } 102 | table.dataTable > tbody > tr.child span.dtr-title { 103 | display: inline-block; 104 | min-width: 75px; 105 | font-weight: bold; 106 | } 107 | -------------------------------------------------------------------------------- /opsweb/static/css/metisMenu.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.1.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumus 7 | * Under MIT License 8 | */ 9 | 10 | .arrow{float:right;line-height:1.42857}.glyphicon.arrow:before{content:"\e079"}.active>a>.glyphicon.arrow:before{content:"\e114"}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.plus-times{float:right}.fa.plus-times:before{content:"\f067"}.active>a>.fa.plus-times{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.plus-minus{float:right}.fa.plus-minus:before{content:"\f067"}.active>a>.fa.plus-minus:before{content:"\f068"} -------------------------------------------------------------------------------- /opsweb/static/css/morris.css: -------------------------------------------------------------------------------- 1 | .morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0} 2 | .morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0} 3 | -------------------------------------------------------------------------------- /opsweb/static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /opsweb/static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /opsweb/static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /opsweb/static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /opsweb/static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /opsweb/static/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/images/sort_asc.png -------------------------------------------------------------------------------- /opsweb/static/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /opsweb/static/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/images/sort_both.png -------------------------------------------------------------------------------- /opsweb/static/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/images/sort_desc.png -------------------------------------------------------------------------------- /opsweb/static/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xl0shk/ops-web/7ebc4efadac337ebae519a43168589ac7fd515c1/opsweb/static/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /opsweb/static/js/dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 3 integration 3 | ©2011-2014 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(){var f=function(c,b){c.extend(!0,b.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'p>>",renderer:"bootstrap"});c.extend(b.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"});b.ext.renderer.pageButton.bootstrap=function(g,f,p,k,h,l){var q=new b.Api(g),r=g.oClasses,i=g.oLanguage.oPaginate,d,e,o=function(b,f){var j,m,n,a,k=function(a){a.preventDefault(); 6 | c(a.currentTarget).hasClass("disabled")||q.page(a.data.action).draw(!1)};j=0;for(m=f.length;j",{"class":r.sPageButton+" "+ 7 | e,"aria-controls":g.sTableId,tabindex:g.iTabIndex,id:0===p&&"string"===typeof a?g.sTableId+"_"+a:null}).append(c("",{href:"#"}).html(d)).appendTo(b),g.oApi._fnBindAction(n,{action:a},k))}};o(c(f).empty().html('