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