• 自动化运维平台搭建


    项目简介:

      项目介绍:自动化运维是未来的趋势,最近学了不少东西,正好通过这个小项目把这些学的东西串起来,练练手。

      基础架构:

    • 服务器端: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">&times;</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)">&laquo;</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)">&raquo;</a></li>
    47             </ul>
    48         </nav>
    49     </div>
    50 </div>

      这个小项目还会继续做下去,期望能达到当初自己设计的那样。。。。。。。

      

    作者:最后一个亮亮 出处: https://www.cnblogs.com/swim/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】
  • 相关阅读:
    内存检测与优化
    iOS逆向工程(1)
    UIBezierPath 概述
    万能弹窗,点击区域外消失
    逆向传值
    蓝牙开发
    pod
    github
    iOS语音
    图像去噪——分割后处理
  • 原文地址:https://www.cnblogs.com/swim/p/7223158.html
Copyright © 2020-2023  润新知