项目简介:
项目介绍:自动化运维是未来的趋势,最近学了不少东西,正好通过这个小项目把这些学的东西串起来,练练手。
基础架构:
- 服务器端:web框架-Django
- 前端:html css jQuery bootstrap
- 脚本:shell
- 适用系统:redhat5.8/redhat6.6
平台已实现功能:
- 中间件和数据库软件的启停和状态检查 (tomcat,nginx,apache,oracle,mysql)
完整功能设计图:
效果图:
架构图(简要):
项目源码:https://github.com/SwimBalance/autoops4
shell脚本
1 #!/bin/sh 2 #Filename:starttomcat.sh 3 #需要传入参数:$1 $2 $3 4 # $1:tomcat的home目录 5 # $2:端口号 6 # $3:启动tomcat超时时长 7 #输出结果说明: 8 # 101:启动成功 9 # 104:启动超时 10 11 #写日志函数 12 log(){ 13 echo `date +"%F %T"`" "$* >> /logs/tomcat.log 14 } 15 16 #开启tomcat函数 17 starttomcat(){ 18 log "[command]:"$0" [parameters]:"$* 19 #启动tomcat前需要调用checktomcat获取tomcat状态 20 status=`. /operation/tomcat/checktomcat.sh $1 $2` 21 #如果tomcat处于运行状态,就不必再启动,把状态信息返回前端 22 if [ $status -eq 101 ];then 23 echo 101 24 #如果tomcat未运行,执行启动操作 25 else 26 su - tomcat -c $1/bin/startup.sh >/dev/null 2>&1 27 #设置count计时 28 count=0 29 #每5秒检查一次tomcat状态,直到检查到tomcat成功启动或者超时 30 status=`. /operation/tomcat/checktomcat.sh $1 $2` 31 until [ $status -eq 101 ] || [ $count -ge $3 ] 32 do 33 sleep 5 34 let count=$count+5 35 status=`. /operation/tomcat/checktomcat.sh $1 $2` 36 done 37 #如果检测到tomcat正常,判断为启动成功,返回状态信息 38 if [ $status -eq 101 ];then 39 echo 101 40 #如果超时还未启动成功,则判断为启动超时,返回启动超时代号104 41 else 42 echo 104 43 fi 44 fi 45 } 46 47 starttomcat $1 $2 $3
views.py:tomcat操作响应函数
1 # 针对tomcat服务器的操作: 2 # 1.首先通过前台获得ID 和 操作 3 # 2.通过ID 丰富信息 4 # 3.形成完整的操作SQL 5 # 4.执行SQL,返回结果 6 # 5.将操作信息及结果写入操作记录表,并将结果返回前台 7 # 6.前台收到信息更新tomcat现在运行状态 8 def operation(request): 9 # 获得前台信息 10 tomcat_id = request.GET.get(\'id\') 11 tomcat_action = request.GET.get(\'action\') 12 oper = request.COOKIES.get(\'loginname\') 13 # 根据ID和action 获得任务信息,并形成完整的操作SQL,都存入taskinfo中 14 taskinfo = get_taskinfo(tomcat_id, tomcat_action, oper) 15 # 传入taskinfo,执行SQL操作,返回目标服务器控制台的结果 16 mytask = Task(taskinfo) 17 result = mytask.execute() 18 if result.isdigit(): 19 taskinfo[\'resulut\'] = result 20 else: 21 taskinfo[\'resulut\'] = \'102\' 22 # 将操作记录写入记录表中,同时更新tomcatdata表中的状态字段 23 genrecords_updatestatus(taskinfo) 24 # 将结果传到前台 25 message = { 26 \'101\': \'Tomcat正常运行.\', 27 \'102\': \'Tomcat异常,请人工检查.\', 28 \'103\': \'Tomcat服务关闭.\', 29 \'104\': \'Tomcat启动超时.\', 30 \'105\': \'Tomcat关闭超时.\', 31 } 32 return JsonResponse({ 33 \'status\': taskinfo[\'resulut\'], 34 \'message\': message[taskinfo[\'resulut\']], 35 }) 36 37 # 根据ID生成taskinfo 38 def get_taskinfo(tomcat_id, tomcat_action, oper): 39 with connection.cursor() as cursor: 40 cursor.execute( 41 \'SELECT id, tomcatport, tomcathome, ipaddress, startwait, stopwait FROM tomcatdata WHERE id = %s\' % tomcat_id 42 ) 43 tomcater = dictfetchall(cursor)[0] 44 serverip = tomcater[\'ipaddress\'] 45 cursor.execute( 46 "SELECT user1,password1 FROM machine_pwd WHERE ipaddress = \'%s\'" % serverip 47 ) 48 userinfo = dictfetchall(cursor)[0] 49 if tomcat_action == \'check_tomcat\': 50 tomcat_home = tomcater[\'tomcathome\'] 51 tomcat_port = tomcater[\'tomcatport\'] 52 command = \'sh /operation/tomcat/checktomcat.sh %s %s \' % (tomcat_home, tomcat_port) 53 elif tomcat_action == \'start_tomcat\': 54 # 需要传入三个参数 home目录/端口号/启动超时时长 55 tomcat_home = tomcater[\'tomcathome\'] 56 tomcat_port = tomcater[\'tomcatport\'] 57 start_wait = tomcater[\'startwait\'] 58 # sh_dir = \'/operation/tomcat/starttomcat.sh\' 59 command = \'sh /operation/tomcat/starttomcat.sh %s %s %s \' % (tomcat_home, tomcat_port, start_wait) 60 elif tomcat_action == \'stop_tomcat\': 61 # 需要传入三个参数 home目录/端口号/启动超时时长 62 tomcat_home = tomcater[\'tomcathome\'] 63 tomcat_port = tomcater[\'tomcatport\'] 64 stop_wait = tomcater[\'stopwait\'] 65 # sh_dir = \'/operation/tomcat/starttomcat.sh\' 66 command = \'sh /operation/tomcat/stoptomcat.sh %s %s %s \' % (tomcat_home, tomcat_port, stop_wait) 67 task_info = { 68 \'id\': tomcat_id, 69 \'action\': tomcat_action, 70 \'oper\': oper, 71 \'ip\': tomcater[\'ipaddress\'], 72 \'user\': userinfo[\'user1\'], 73 \'pwd\': userinfo[\'password1\'], 74 \'cmd\': command, 75 \'result\': \'\' 76 } 77 return task_info 78 79 80 # 写入操作记录并更新tomcat状态 81 def genrecords_updatestatus(taskinfo): 82 with connection.cursor() as cursor: 83 sqlstatement1 = "insert into audit_log (oper_user, oper_command, oper_message) VALUES (\'%s\', \'%s\', \'%s\')" % ( 84 taskinfo[\'oper\'], taskinfo[\'cmd\'], taskinfo[\'resulut\']) 85 sqlstatement2 = "update tomcatdata set status = %d where id = %r" % (int(taskinfo[\'resulut\']), taskinfo[\'id\']) 86 cursor.execute(sqlstatement1) 87 cursor.execute(sqlstatement2)
Task类
1 import paramiko 2 3 4 class Task(object): 5 def __init__(self, task_info): 6 self.task_info = task_info 7 8 def create_connect(self): 9 # 创建SSH对象 10 connectObj = paramiko.SSHClient() 11 # 把要连接的机器添加到known_hosts文件中 12 connectObj.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 13 # 连接服务器 14 connectObj.connect( 15 hostname=self.task_info[\'ip\'], 16 username=self.task_info[\'user\'], 17 password=self.task_info[\'pwd\'], 18 port=22, 19 timeout=10 20 ) 21 # 判断是否连接成功 22 ################### 23 return connectObj 24 25 def execute(self): 26 try: 27 connectObj = self.create_connect() 28 except: 29 return \'102\' 30 cmd = self.task_info[\'cmd\'] 31 stdin, stdout, stderr = connectObj.exec_command(cmd) 32 result = stdout.read() 33 connectObj.close() 34 if not result: 35 result = stderr.read().strip() 36 return result.decode().strip()
js文件
1 $(function () { 2 $("ul[id=\'servicemgr\'] li").click(function () { 3 <!-- 导入workPage--> 4 if (this.id == \'toms\') { 5 $("#workpage").empty().load("/static/maintenance/html/workpage.html #tom_workpage"); 6 $.ajax({ 7 type: "GET", 8 url: "./../tomcatData/", 9 datatype: \'json\', 10 data: {page: 1}, 11 success: function (datas) { 12 loadtomcatdata(datas) 13 } 14 }); 15 } else if (this.id == \'oras\') { 16 $("#workpage").empty().load("/static/maintenance/html/workpage.html #ora_workpage"); 17 $.ajax({ 18 type: "GET", 19 url: "./../oracleData/", 20 datatype: \'json\', 21 success: function (datas) { 22 loadoracledata(datas) 23 } 24 }) 25 } 26 }); 27 }); 28 29 // 针对tomcat服务器的操作 30 function opt_tomcat(obj) { 31 var tomcat_mes = $("#tomcat_mes"); 32 tomcat_mes.empty().append("正在玩命操作,请等待…"); 33 var id = obj.id; 34 var action = obj.name; 35 $.ajax({ 36 type: \'Get\', 37 url: \'./../operation\', 38 data: {\'id\': id, \'action\': action}, 39 success: function (data) { 40 tomcat_mes.empty().append(data[\'message\']); 41 //更新状态 42 if (data[\'status\'] == \'101\') { 43 $(obj).parent().prevAll(\'.status\').children(\'span\').attr(\'class\', \'glyphicon glyphicon-ok-sign\') 44 } else if (data[\'status\'] == \'102\' || data[\'status\'] == \'104\' || data[\'status\'] == \'105\') { 45 $(obj).parent().prevAll(\'.status\').children(\'span\').attr(\'class\', \'glyphicon glyphicon-exclamation-sign\') 46 } else if (data[\'status\'] == \'103\') { 47 $(obj).parent().prevAll(\'.status\').children(\'span\').attr(\'class\', \'glyphicon glyphicon-remove-sign\') 48 } 49 } 50 }) 51 } 52 // 分页 53 function page(obj) { 54 var page_number = $(obj).text(); 55 $.ajax({ 56 type: "GET", 57 url: "./../tomcatData/", 58 datatype: \'json\', 59 data: {page: page_number}, 60 success: function (datas) { 61 loadtomcatdata(datas) 62 } 63 }); 64 } 65 //导入tomcat数据 66 function loadtomcatdata(datas) { 67 var text = $(\'.text\'); 68 text.empty(); 69 var html = \'\'; 70 for (var i = 0; i < datas.length; i++) { 71 var id = datas[i][\'id\']; 72 var ip = datas[i][\'ipaddress\']; 73 var host = datas[i][\'machine\']; 74 var dec = datas[i][\'description\']; 75 var status = datas[i][\'status\']; 76 html += \'<tr>\'; 77 html += \'<td>\' + id + \'</td>\'; 78 html += \'<td>\' + ip + \'</td>\'; 79 html += \'<td>\' + host + \'</td>\'; 80 html += \'<td>\' + dec + \'</td>\'; 81 // html += \'<td class="status">\' + status + \'</td>\'; 82 //更新状态 83 if (status == \'101\') { 84 html += \'<td class="status"><span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span></td>\'; 85 } else if (status == \'102\' || status == \'104\' || status == \'105\') { 86 html += \'<td class="status"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span></td>\'; 87 } else if (status == \'103\') { 88 html += \'<td class="status"><span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span></td>\'; 89 } 90 html += \'<td>\' + \'<button id=\' + id + \' onclick="opt_tomcat(this)" name="check_tomcat" class="btn btn-default" data-toggle="modal" data-target="#myModal">\'; 91 html += \'<span class="glyphicon glyphicon-check" aria-hidden="true"></span></button></td>\'; 92 html += \'<td>\' + \'<button id=\' + id + \' onclick="opt_tomcat(this)" name="start_tomcat" class="btn btn-default" data-toggle="modal" data-target="#myModal">\'; 93 html += \'<span class="glyphicon glyphicon-play" aria-hidden="true"></span></button></td>\'; 94 html += \'<td>\' + \'<button id=\' + id + \' onclick="opt_tomcat(this)" name="stop_tomcat" class="btn btn-default" data-toggle="modal" data-target="#myModal">\'; 95 html += \'<span class="glyphicon glyphicon-stop" aria-hidden="true"></span></button></td>\'; 96 html += \'</tr>\'; 97 } 98 text.append(html); 99 100 } 101 //搜索栏 102 function searchtomcat() { 103 104 var search_val = $(\'#search_tom\').val(); 105 $.ajax({ 106 type: "GET", 107 url: "/../searchtomcat/", 108 data: {\'data\': search_val}, 109 datatype: "json", 110 success: function (datas) { 111 loadtomcatdata(datas); 112 $(\'#preandnext\').empty() 113 } 114 }) 115 }
index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 {% load static %} 5 <title>自动化运维</title> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <!-- 引入 Bootstrap --> 8 <link href="{% static \'maintenance/bootstrap3.3.7/css/bootstrap.min.css\' %}" rel="stylesheet"> 9 <meta charset="UTF-8"> 10 <!-- 导入Jquery文件--> 11 <script src="{% static \'maintenance/js/jquery-3.2.1.min.js\' %}"></script> 12 <!--导入bootstrap中的js 插件--> 13 <script src="{% static \'maintenance/bootstrap3.3.7/js/bootstrap.min.js\' %}"></script> 14 <!--导入自己的js文件--> 15 <script src="{% static \'maintenance/js/show_workpage.js\' %}"></script> 16 <style> 17 .glyphicon-ok-sign{color:green} 18 .glyphicon-exclamation-sign{color:crimson;} 19 .glyphicon-remove-sign{color:darkgray} 20 </style> 21 </head> 22 <body> 23 <div class=" container-fluid"> 24 <div class="row"> 25 <div class="col-lg-12" style="text-align:center;background-color: #9acfea"> 26 <h3>AUTO OPERATION 27 <small>自动化运维平台</small> 28 </h3> 29 </div> 30 </div> 31 <div class="row "> 32 <div class="col-lg-2" style="margin-left :-15px;"> 33 <ul class="nav nav-pills nav-stacked"> 34 <li id="home" role="presentation" class="active"><a href="javascript:void(0)">主页</a></li> 35 <li class="active"> 36 <a href="#servicemgr" class="nav-header collapsed " data-toggle="collapse"> 37 <i class="glyphicon glyphicon-cog"></i>服务管理 38 <span class="pull-right glyphicon glyphicon-chevron-toggle"></span> 39 </a> 40 <ul id="servicemgr" class="nav nav-list collapse in" style="list-style: none"> 41 <li id="oras" role="presentation"><a href="javascript:void(0)">Oracle服务管理</a></li> 42 <li id="mysqls" role="presentation"><a href="javascript:void(0)">MySQL服务管理</a></li> 43 <li id="toms" role="presentation"><a href="javascript:void(0)">Tomcat服务管理</a></li> 44 <li id="apache" role="presentation"><a href="javascript:void(0)">Apache服务管理</a></li> 45 <li id="nginx" role="presentation"><a href="javascript:void(0)">NGINX服务管理</a></li> 46 </ul> 47 </li> 48 <li class="active"> 49 <a href="#systemsetting" class="nav-header collapsed " data-toggle="collapse"> 50 <i class="glyphicon glyphicon-cog"></i>系统管理 51 <span class="pull-right glyphicon glyphicon-chevron-toggle"></span> 52 </a> 53 <ul id="systemsetting" class="nav nav-list collapse in"> 54 <li class="active"><a href="#"><i class="glyphicon glyphicon-user"></i> 用户信息维护</a></li> 55 <li><a href="javascript:void(0)"><i class="glyphicon glyphicon-th-list"></i> 应用系统信息维护</a></li> 56 <li><a href="javascript:void(0)"><i class="glyphicon glyphicon-asterisk"></i> 服务器信息维护</a></li> 57 <li><a href="javascript:void(0)"><i class="glyphicon glyphicon-eye-open"></i> 日志查看</a></li> 58 </ul> 59 </li> 60 </ul> 61 </div> 62 <div class="col-lg-10"> 63 <div id="workpage"></div> 64 <!-- 模态框(Modal) --> 65 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" 66 aria-hidden="true"> 67 <div class="modal-dialog"> 68 <div class="modal-content"> 69 <div class="modal-header"> 70 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 71 <h4 class="modal-title" id="myModalLabel">操作结果</h4> 72 </div> 73 <div class="modal-body" id="tomcat_mes"></div> 74 <div class="modal-footer"> 75 <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> 76 </div> 77 </div><!-- /.modal-content --> 78 </div><!-- /.modal --> 79 </div> 80 </div> 81 </div> 82 <div class="page-footer"></div> 83 </div> 84 85 </body> 86 </html>
workpage.html
1 <!-- tomcat工作页--> 2 <div id="tom_workpage"> 3 <div style="border: 1px;"> 4 <div class="row"> 5 <ol class="breadcrumb"> 6 <li><a href="#">Home</a></li> 7 <li class="active">Tomcat</li> 8 </ol> 9 <div class="row"> 10 <div class="col-lg-6" style="float: right"> 11 <div class="input-group"> 12 <input id="search_tom" type="text" class="form-control" placeholder="IP/服务器名称" onkeydown="if(event.keyCode==13) {searchtomcat()}"> 13 <span class="input-group-btn"> 14 <button class="btn btn-default" type="button" onclick="searchtomcat()">查找</button> 15 </span> 16 </div><!-- /input-group --> 17 </div><!-- /.col-lg-6 --> 18 </div><!-- /.row --> 19 <table class="table table-hover table-condensed"> 20 <caption><strong>Tomcat应用服务器清单</strong></caption> 21 <thead> 22 <tr> 23 <th>ID</th> 24 <th>IP</th> 25 <th>主机名</th> 26 <th>概要</th> 27 <th>状态</th> 28 <th>检查</th> 29 <th>开启</th> 30 <th>停止</th> 31 </tr> 32 </thead> 33 <tbody class="text"> 34 35 </tbody> 36 </table> 37 </div> 38 <nav id="preandnext" style="text-align: center"> 39 <ul class="pagination" style="margin: 0"> 40 <li onclick="previousPage(this)"><a href="javascript:void(0)">«</a></li> 41 <li onclick="page(this)"><a href="javascript:void(0)">1</a></li> 42 <li onclick="page(this)"><a href="javascript:void(0)">2</a></li> 43 <li onclick="page(this)"><a href="javascript:void(0)">3</a></li> 44 <li onclick="page(this)"><a href="javascript:void(0)">4</a></li> 45 <li onclick="page(this)"><a href="javascript:void(0)">5</a></li> 46 <li onclick="nextPage(this)"><a href="javascript:void(0)">»</a></li> 47 </ul> 48 </nav> 49 </div> 50 </div>
这个小项目还会继续做下去,期望能达到当初自己设计的那样。。。。。。。