项目简介:
项目介绍:自动化运维是未来的趋势,最近学了不少东西,正好通过这个小项目把这些学的东西串起来,练练手。
基础架构:
- 服务器端: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 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 += ''; 77 html += ' '; 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 }' + id + ' '; 78 html += '' + ip + ' '; 79 html += '' + host + ' '; 80 html += '' + dec + ' '; 81 // html += '' + status + ' '; 82 //更新状态 83 if (status == '101') { 84 html += ''; 85 } else if (status == '102' || status == '104' || status == '105') { 86 html += ' '; 87 } else if (status == '103') { 88 html += ' '; 89 } 90 html += ' ' + ' '; 92 html += '' + ' '; 94 html += '' + ' '; 96 html += '
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 8 <link href="{% static 'maintenance/bootstrap3.3.7/css/bootstrap.min.css' %}" rel="stylesheet"> 9 <meta charset="UTF-8"> 10 11 <script src="{% static 'maintenance/js/jquery-3.2.1.min.js' %}">script> 12 13 <script src="{% static 'maintenance/bootstrap3.3.7/js/bootstrap.min.js' %}">script> 14 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 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> 78 div> 79 div> 80 div> 81 div> 82 <div class="page-footer">div> 83 div> 84 85 body> 86 html>
workpage.html
1 2 <div id="tom_workpage"> 3 <div style="border: 1px;"> 4 <div class="row"> 5 <ol class="breadcrumb"> 6 <li><a href="#">Homea>li> 7 <li class="active">Tomcatli> 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> 17 div> 18 div> 19 <table class="table table-hover table-condensed"> 20 <caption><strong>Tomcat应用服务器清单strong>caption> 21 <thead> 22 <tr> 23 <th>IDth> 24 <th>IPth> 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)">1a>li> 42 <li onclick="page(this)"><a href="javascript:void(0)">2a>li> 43 <li onclick="page(this)"><a href="javascript:void(0)">3a>li> 44 <li onclick="page(this)"><a href="javascript:void(0)">4a>li> 45 <li onclick="page(this)"><a href="javascript:void(0)">5a>li> 46 <li onclick="nextPage(this)"><a href="javascript:void(0)">»a>li> 47 ul> 48 nav> 49 div> 50 div>
这个小项目还会继续做下去,期望能达到当初自己设计的那样。。。。。。。