flask+ansible 打造自己的自动化运维平台

这篇具有很好参考价值的文章主要介绍了flask+ansible 打造自己的自动化运维平台。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

      随着企业信息化要求越来越高,云化架构带来挑战和冲击,海量设备的运维压力也是越来越大,虽然有了批量操作工具,但自动化运维工具操作主要还是依赖于手工执行(脚本小子),手工执行又存在着操作流程不规范,操作记录不可控,批量脚本不统一等多个问题,有较大风险造成人为误操作的可能。

      一直以来是想做个系统来规避这些问题,前期也有过其他开发团队开发过此类产品试用,但开发不懂运维,测试起来很多问题,这些问题后来因为开发项目无法支撑流产了,也没实际用起来。

     批量操作的工具,用过puppet、saltstack、ansible,管理资产超过5000+,目前在用ansible。 Ansible了解过有个官方系统tower,测试装了下,人太高大上,也不是很符合我们批量操作使用的场景。

     近来时间比较充裕,学习了下python的开发框架,自己动手,按照自己的需求来开发,可以更贴合使用。以前觉得开发好难好难,真动手去做了,做个简单系统自己内部使用还是可以的~

    系统中使用的框架是python flask + ansible+mysql。  

    整个demo系统资源也上传到了共享,大家有感兴趣的,可以自己动手玩玩~

    https://download.csdn.net/download/vincent0920/88768831

二、系统设计

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

系统整体分7个模块:
登录页面:系统的入口,所有其他页面需要做登录控制,只有登录后才能使用。登录只简单做下账号密码验证,什么双因子,验证码防爆力破解的安全要求后期看需要再实现了。

首页:用户登录后,展示的平台整体情况,简单的图表展示,展示一些统计类,top类数据,趋势类数据。

接入清单:对纳管主机的管控视图,支持常规字段的查询。

主机导入:支持页面导入自定义主机分组,导入结果入库,页面支持主机组信息查询。

模板页面:自定义模板的上传页面,规定模板上传的格式,上传后支持查询。

作业页面:可以基于模板去配置作业,配置作业后支持查询记录,支持作业的一个测试拨测并可查询测试结果。

作业记录:作业正式执行的界面,带入测试的记录,支持执行按钮、异步作业和执行结果查询。

三、实现过程 

项目Flask程序的目录结构如下:

ansible/

├── app.py            ----flask主程序

├── blueprints        ----蓝图目录 各模块后台处理代码

├── config.py         ----配置文件 数据库等配置文件

├── decorators.py     ----装饰器  代码重用文件

├── exts.py           ----解决循环引用的问题

├── migrations        ----数据库迁移目录 数据库类操作

├── models.py         ----数据库模型文件 数据库表初始化设置

├── mycelery.py       ----异步处理的代码

├── scrtpts           ----ansible 调用的脚本目录

├── static            ----前台页面的静态文件 css,js,image等

└── templates         ----前台页面的html模板

1、登录页面      

     套用的是之前学习过的一个测试项目登录页面,本来还涉及邮箱注册的功能,考虑到我这个不放在公网使用,就修改去掉了,用户账号增加通过后台录入数据。

     登录需要做个登录控制,每个页面访问前需要先登录。可以设置登录装饰器如下:

def login_required(func):

    # 保留func的信息

    @wraps(func)

    # func(a,b,c)

    # func(1,2,c=3)

    def inner(*args, **kwargs):

        if g.user:

            return func(*args, **kwargs)

        else:

            return redirect(url_for("auth.login"))

    return inner

    登录时校验前端提交的数据可符合要求,可通过wtforms模块。

form.py

# Form:主要就是用来验证前端提交的数据是否符合要求

class LoginForm(wtforms.Form):

    username = wtforms.StringField(validators=[Length(min=3, max=8, message="用户格式错误!")])

    password = wtforms.StringField(validators=[Length(min=6, max=20, message="密码格式错误!")])

登录模块代码:

from flask import Blueprint, render_template, jsonify, redirect, url_for, session
from exts import  db
from flask import request
import string
import random
from .forms import  LoginForm
from models import UserModel
from werkzeug.security import generate_password_hash, check_password_hash

# /auth
bp = Blueprint("auth", __name__, url_prefix="/auth")

@bp.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        form = LoginForm(request.form)
        if form.validate():
            username = form.username.data
            password = form.password.data
            user = UserModel.query.filter_by(username=username).first()
            if not user:
                print("用户在数据库中不存在!")
                return redirect(url_for("auth.login"))
            if check_password_hash(user.password, password):
                # cookie:
                # cookie中不适合存储太多的数据,只适合存储少量的数据
                # cookie一般用来存放登录授权的东西
                # flask中的session,是经过加密后存储在cookie中的
                session['user_id'] = user.id
                return redirect("/")
            else:
                print("密码错误!")
                return redirect(url_for("auth.login"))
        else:
            print(form.errors)
            return redirect(url_for("auth.login"))

@bp.route("/logout")
def logout():
    session.clear()
    return redirect("/")

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

2、首页

     主要是做个看板展示内容,包含图表,例如对主机接入的统计数字、对作业任务的统计数字、对模板的统计数字;再加上从不同维度不同图形展示趋势(散点图、柱形图、饼形图)。主要工作在前端页面设计上,后端只需匹配查询具体数值传递给前端即可。

    前端中,首先定义图表展示的区间,我把分成了3部分区域,分别是标题+数字框+趋势图。其次,在趋势图这块,用的是echarts模板,有示例很好用,可参考,下载模板即插即用

Examples - Apache ECharts

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

3、接入清单(inventory)

      纯查询的页面,主要是用来查询全量纳管主机的一个拨测全局情况,里面有些字段可以和cmdb进行联动,例如业务系统、系统类型、系统分类,通过关联的字段,后期也可根据这些字段做些自定义作业。

后端主要涉及一个分页实现:

page = request.args.get(get_page_parameter(), type=int, default=1)
limit=10
start = (page - 1) * limit
end = start + limit
pagadata=data.slice(start, end)
pagination=Pagination(page=page,total=data.count(), bs_version=3, prev_label="上一页", next_label="下一页", per_page=limit)
total_page = pagination.total

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

4、主机导入

     导入实际是往数据库插入数据,不往主机上上传文件。再导入前先写个导入基本指导说明,导入后在页面下午展示导入过的记录情况。

    导入时除了往数据库插入数据,还需要向系统中hosts文件新增主机组分组数据。

后端代码:

@bp.route('/toexcel',methods = ['GET','POST'])
@login_required
def toExcel():
    if request.method == 'POST':
        file = request.files.get('file')
        f = file.read()
        data_file = xlrd.open_workbook(file_contents=f)
        table = data_file.sheet_by_index(0)
        nrows = table.nrows
        ncols = table.ncols
        hostgroup = table.row_values(0)[1]
        with open('/etc/ansible/hosts', 'a') as file:
           file.write('['+hostgroup+']'+'\n')
        
        with open('/etc/ansible/hosts', 'a') as file:
        
         for i in range(0, nrows):
            row_date = table.row_values(i)
            ip = row_date[0]
            marktype = row_date[1]
            adduser = g.user.username
            jierudata = db.session.query(InventoryModel.jieruinfo).filter(InventoryModel.ip==ip).first()
            try:
               jieruinfo = jierudata[0]
            except TypeError:
               jieruinfo = '地址未接入'
                      
            addhost = GroupModel(ip=ip, marktype=marktype, adduser=adduser, jieruinfo=jieruinfo)
            db.session.add(addhost)
            db.session.commit()    
            file.write(ip+'\n')       

    data=GroupModel.query.filter(GroupModel.id>0) 
    page = request.args.get(get_page_parameter(), type=int, default=1)
    limit=10
    start = (page - 1) * limit
    end = start + limit
    pagadata=data.slice(start, end)
    pagination = Pagination(page=page, total=data.count(), bs_version=3, prev_label="上一页", next_label="下一页", per_page=limit)
    total_page = pagination.total
     
    return render_template("execl.html", pagination=pagination, pagadata=pagadata,total_page=total_page)

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

5、模板页面

       定义好制作模板的填写要素,首先模板名得具有唯一性,后续作业是需要基于模板名制作;其次模板内容这里,目前只考虑使用ansible的testping、shell、playbook的三个模块,当执行脚本时,也会引用此处的模板内容,也就是脚本内容,例如:

  1. 当执行testping时,内容后端写死了命令格式,此处不需调用模板内容。
  2. 当执行shell时,模板内容需要填写需要操作的命令内容,例如date,后端执行就会直接调用执行date命令
  3. 当执行playbook时,此时模板内容需要填写剧本脚本名称,例如test.yml。路径统一放在script目录下。(此处考虑执行脚本的规范统一,暂不支持界面随意直接上传脚本)

后端代码:

@bp.route('/templateadd',methods = ['GET','POST'])
@login_required
def addtemp():
        f1 = request.args.get("f1")
        f2 = request.args.get("f2")
        f3 = request.args.get("f3")
        f4 = request.args.get("f4")

        if len(f1)==0 and len(f2)==0 and len(f3)==0 and len(f4)==0:
           data=TemplateModel.query.filter(TemplateModel.id>0)
        else:
           adduser = g.user.username
           addtemp = TemplateModel(tempname=f1, temptype=f2, description=f3, tempsrc=f4, createuser=adduser)
           db.session.add(addtemp)
           db.session.commit()
           data=TemplateModel.query.filter(TemplateModel.id>0) 
           
        
        page = request.args.get(get_page_parameter(), type=int, default=1)
        limit=5
        start = (page - 1) * limit
        end = start + limit
        pagadata=data.slice(start, end)
        pagination = Pagination(page=page, total=data.count(), bs_version=3, prev_label="上一页", next_label="下一页", per_page=limit)
        total_page = pagination.total
     
        return render_template("template.html", pagination=pagination, pagadata=pagadata,total_page=total_page)
              
@bp.route('/search/template')
@login_required
def search_template():
        f5 = request.args.get("f5")
        f6 = request.args.get("f6")
        f7 = request.args.get("f7")
        f8 = request.args.get("f8")
        f9 = request.args.get("f9")
        

        if len(f5)==0 and len(f6)==0 and len(f7)==0 and len(f8)==0 and len(f9)==0:
           data=TemplateModel.query.filter(TemplateModel.id>0) 
        else:      
           data=TemplateModel.query.filter(TemplateModel.tempname.like('%'+f5+'%'),TemplateModel.temptype.like('%'+f6+'%'),TemplateModel.description.like('%'+f7+'%'),TemplateModel.tempsrc.like('%'+f8+'%'),TemplateModel.createuser.like('%'+f9+'%'))
               
        page = request.args.get(get_page_parameter(), type=int, default=1)
        limit=5
        start = (page - 1) * limit
        end = start + limit
        pagadata=data.slice(start, end)
        pagination = Pagination(page=page, total=data.count(), bs_version=3, prev_label="上一页", next_label="下一页", per_page=limit)
        total_page = pagination.total

        return render_template("template.html", pagination=pagination, pagadata=pagadata,total_page=total_page)

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

6、作业页面

    定义好制作作业的填写要素,首先作业名也得具有唯一性,作业需要基于模板名制作;其次需要关联前面添加的主机组(执行时调用的IP组)。

   作业添加完,支持对作业的测试拨测,定义一台测试主机,要求是作业在执行前必须先执行作业测试,测试完刷新测试的标签并展示记录。

   测试输出结果,可能会较多的文字输出,所以做了一个链接展示,点击后可详细展示输出内容。

   这里没有直接调用ansible的api,直接是调用的command模块,系统的shell命令来执行ansible相关的命令,需要考虑的是对ansible的输出结果再做格式化的调整。

后端代码(ansible调用部分):

          if tempname=='连通检测':        
              command = 'ansible %s -m ping -o' % groupname
              result = ""
              try:
                  result = os.popen(command).read()
              except Exception as e:
                  resultinfo=("执行Ansible脚本发生异常,异常信息:%s" % e)
              if result:
                  resultinfo=("返回结果:%s" % result)
              else:
                  resultinfo=("返回结果为空")
              
              TasktestviewModel.query.filter_by(taskname=f11).update({'resultinfo':resultinfo,'testtaginfo':testtaginfo})   
              db.session.commit()           
              data=TasktestviewModel.query.filter(TasktestviewModel.id>0)    
              
           if tempname=='命令执行':            
              command = f"ansible {groupname} -m shell -a \" {content} \" -o"
              result = ""
              try:
                  result = os.popen(command).read()
              except Exception as e:
                  resultinfo=("执行Ansible脚本发生异常,异常信息:%s" % e)
              if result:
                  resultinfo=("返回结果:%s" % result)
              else:
                  resultinfo=("返回结果为空")
              
              TasktestviewModel.query.filter_by(taskname=f11).update({'resultinfo':resultinfo,'testtaginfo':testtaginfo})   
              db.session.commit()           
              data=TasktestviewModel.query.filter(TasktestviewModel.id>0)    
 
           if tempname=='任务编排':   
              command = f"ansible-playbook ./scrtpts/{content} -e group={groupname} |sed \'s/**\*/******************************/g\'"
              result = ""
              try:
                  result = os.popen(command).read()
              except Exception as e:
                  resultinfo=("执行Ansible脚本发生异常,异常信息:%s" % e)
              if result:
                  resultinfo=("返回结果:%s" % result)
              else:
                  resultinfo=("返回结果为空")
              
              TasktestviewModel.query.filter_by(taskname=f11).update({'resultinfo':resultinfo,'testtaginfo':testtaginfo})   
              db.session.commit()           
              data=TasktestviewModel.query.filter(TasktestviewModel.id>0)    

 
           else:   
               resultinfo="该作业类型不支持"

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

7、作业记录

    作业的正式执行是放在作业记录中,实现逻辑和作业测试模块基本一致,只是这个步骤中会去调用主机组信息,对主机组里所有ip去执行相应操控。

    需要考虑的一个问题就是作业执行,涉及机器多时,必然ansible执行时间会比较长,此时需要去设置异步处理,flask的celery模块可以实现该功能(前提还需要安装下redis),将作业任务加到异步队列中执行,这样前端可不必等作业执行直接返回业务,等ansible执行完可以再去看执行结果即可。(celery还可去获取任务具体执行的状态,例如进行中、已完成等信息,后期可考虑再加上。)

后端代码:

Celery部分

# 创建celery对象

def make_celery(app):

  celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],

                  broker=app.config['CELERY_BROKER_URL'])

  TaskBase = celery.Task

  class ContextTask(TaskBase):

    abstract = True



    def __call__(self, *args, **kwargs):

      with app.app_context():

        return TaskBase.__call__(self, *args, **kwargs)

  celery.Task = ContextTask

  app.celery = celery

  # 添加任务

  celery.task(name="do_command")(do_command)

  return celery

###后台执行命令

celery -A app.celery worker --loglevel=info -P gevent   --logfile="/root/celery.log" &

效果展示:

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

flask+ansible 打造自己的自动化运维平台,自动化运维,运维,flask,ansible

四、总结收获

       一直以来从没学习过开发,到这次是做的第二个测试项目,一个人摸索着,也算是完整的做完了两个项目。从一开始觉得很难入手,到一步一步做完,最后感觉其实也不是很难,很多事就是这样,万事开头难,真正开始做起来后,就意味着你离目标就会越来越近。

       也是通过这样一个实际运维需求转化的开发需求实操案例,进一步加深了对python flask的了解和使用。系统前端没有ui的美化,主打一个简(土)单(到)明(掉)了(渣)。但麻雀虽小,也算是五脏俱全了,个人测试使用应该是可以满足,很多其他方面的优化和完善内容,之后再来学习补充咯!

     There are many things that can not be broken!

     如果觉得本文对你有帮助,欢迎点赞、收藏、评论!文章来源地址https://www.toymoban.com/news/detail-817257.html

到了这里,关于flask+ansible 打造自己的自动化运维平台的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 自动化运维ansible(role)

    一、role的介绍 1、Roles称为角色,本质上是为简化playbook配置文件而产生的一种特殊的方法。 2、简单来说,roles就是将原本在一个yaml中的文件进行规则化分散,封装到不同的目录下,从而简化playbook的yaml配置文件大小。从其实现方法上来看,类似于软件开发上的代码封装。

    2024年02月07日
    浏览(33)
  • Ansible自动化运维工具

    Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。 ansible 自动化运维工具(机器管理工具) 可以实现批量管理多台(成百上千)主机,应用级

    2024年02月14日
    浏览(44)
  • 自动化运维工具之Ansible

    Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主机。比如以前需要切换到每个主机上执行的一或多个

    2024年02月08日
    浏览(65)
  • 自动化运维——ansible (五十二) (01)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 一、概述 1.1 为什么要用自动化运维软件 1.2 自动化运维 1.3 自动化运维要注意的方面 1.4 自动化运维主要关注的方面  1.5 常见的开源自动化运维软件 1.6 自动化运维软件一般安装在哪 二、ansibl

    2024年02月09日
    浏览(42)
  • 【Ansible】Ansible自动化运维工具之playbook剧本

      简单来说,playbooks是一种简单的配置管理系统与多机器部署系统的基础。与现有的其他系统有不同之处,且非常适合复杂应用的部署。   Playbooks 可用于声明配置,更强大的地方在于,playbooks可以编排有序的去执行过程,甚至做到多组机器间来回有序的执行特别指定的

    2024年02月14日
    浏览(36)
  • Linux:ansible自动化运维工具

    当前所有执行权限我是在root下执行的,如果提示权限之类的,可以在每句命令前  加上 sudo     ansible主服务器  192.168.0.194         另外两个客户端分别为 192.168.0.193   192.168.0.192 软件只需要在主服务器上安装,客户端不需要去安装软件,因为他们相互使用的是ssh 只需要

    2024年02月11日
    浏览(41)
  • Ansible 自动化运维工具(完善版)

    目录  Ansible概述 Ansible特点 Ansible应用 1、使用者 2、Ansible工具集合 3、作用对象 Ansible的搭建 环境 ansible主机 1、ansible 2、Ansible-doc Ansible模块 1.command模块 2.shell模块 3.raw模块 Ansible是最近非常火的一款开源运维自动化工具,通过Ansible可以实现运维自动化,提高运维工程师的工

    2024年02月16日
    浏览(40)
  • 自动化运维工具——Ansible学习(二)

    目录 一、handlers和notify结合使用触发条件 1.新建httpd.yml文件 2.复制配置文件到ansible的files目录中 3.卸载被控机已安装的httpd 4.执行httpd.yml脚本 5.更改httpd.conf配置文件 6.使用handlers 7.重新执行httpd.yml脚本 8.检查被控机的端口号是否改变 9.handlers也可以触发多个 二、tags 1.通过指定

    2024年02月16日
    浏览(40)
  • Ansible自动化运维工具的认识

    目录 一、Ansible概述 二、Ansible特点 三、Ansible应用 1、使用者 2、Ansible工具集合 3、作用对象 四、Ansible的搭建 1、实验环境 2、环境准备 Ansible: 3、创建ssh免密交互登录 client端环境准备 五、Ansible配置 六、Ansible命令 1、ansible 实验案例: 1.检查所有主机是否存活 2.列出Rich组中

    2024年02月16日
    浏览(43)
  • 自动化运维工具-------Ansible(超详细)

    Ansible是自动化运维工具,基于Python开发,分布式,无需客户端,轻量级,实现了批量系统配置、批量程序部署、批量运行命令等功能, ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架 。 1)、no agents:不需要在

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包