美文网首页运维驿站python自动化运维DevOPS
授之以渔-运维平台发布模块二(Jenkins篇)

授之以渔-运维平台发布模块二(Jenkins篇)

作者: 大Q的梦想 | 来源:发表于2017-06-09 14:29 被阅读562次

    接上篇《授之以渔-运维平台发布模块一(Jenkins篇)》,今天介绍下结合着Saltstack的MasterEven,用来做发布系统的结果监控。

    一、Event介绍

    SaltStack 0.10版本中, 新增了Event系统, 官方在 Release Notes 对其描述如下:

    The Salt Master now comes equipped with a new event system. This event system has replaced some of the back end of the Salt client and offers the beginning of a system which will make plugging external applications into Salt. The event system relies on a local ZeroMQ publish socket and other processes can connect to this socket and listen for events. The new events can be easily managed via Salt's event library.
    同时官方也在 Salt Event系统 页面中提供了监听event的例子程序, 基于其进行下Event系统学习.
    我们所需要的就是监听event,然后把结果存储到Mysql,Redis之类,以便于我们后续进行处理。

    二、Event代码:

    import salt.utils.event
    import redis
    
    def redis_conect_db6():
        try:
            r = redis.StrictRedis('172.18.11.126', 6379, 6)
        except:
            pass
        return r
    
    event = salt.utils.event.MasterEvent('/var/run/salt/master')
    for data in event.iter_events(full=True):
        r = redis_conect_db6()
        ret = data['data']
        if 'salt/job/' in data['tag']:
            if ret.has_key("id") and ret.has_key("return") and ret.has_key("fun") :
                if ret['fun'] != 'mine.update':
                    if len(ret['fun_args']) >0 and 'wwwlogs' not in ret['fun_args'][0]:
                        print data
                        print "====================================================="
                        if ret['fun'] == 'pkg.get_repo' and ret['return'] != {}:
                            r.set('%s:%s-%s'%(ret['return']['name'],ret['id'],ret['fun']), ret)
                        elif ret['fun'] == 'pkg.upgrade_available' :
                            r.set('%s:%s-%s'%(ret['fun_args'][0],ret['id'],ret['fun']), ret)
                        elif ret['fun'] == 'pkg.install' and ret['return'] != {}:
                            r.set('%s:%s-%s'%(ret['fun_args'][0],ret['id'],ret['fun']), ret)
    
    

    这段event脚本的大体实现了过滤一些非必要信息,把fun中包含pkg.get_repo(验证Yum是否存在),pkg.upgrade_available(验证Yum是否更新),pkg.install(安装)存储到Redis中。然后我只需要去Redis中取出数据,并通过highcharts.js汇出图即可。

    三、后端处理Redis数据绘图代码:

    @login_required
    @my_permissionVerify
    def release_status(request):
        if 'id' in request.GET:
            svn_name = request.GET['id']
            Svn_name = Svn.objects.get(svn_name = svn_name)
            r = redis_conect_db6()
            svn_list = []
            nodes = [{"area":0,"status":2,"no":0,"parent":[],"label":"%s" % str(Svn_name.svn_name)}]
            for svn_host in (Svn_name.svn_hosts).split(','):
                area_dict1 = {}
                area_dict2 = {}
                area_dict3 = {}
                svn_list_dict = {}
                area_dict1["area"] = 1
                area_dict1["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                area_dict1["label"] = "%s" % str(svn_host)
                area_dict1["parent"] = [{"parea":0,"pno":0}]
                area_dict1["status"] = 0
                nodes.append(area_dict1)
                area_dict2["area"] = 2
                area_dict2["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                area_dict2["label"] = "%s" % str(svn_host)
                area_dict2["parent"] = [{"parea":1,"pno":int(area_dict2["no"])}]
                area_dict2["status"] = 0
                nodes.append(area_dict2)
                area_dict3["area"] = 3
                area_dict3["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                area_dict3["label"] = "%s" % str(svn_host)
                area_dict3["parent"] = [{"parea":2,"pno":int(area_dict3["no"])}]
                area_dict3["status"] = 0
                nodes.append(area_dict3)
                """排除同一个主机,多个项目"""
                try:
                    if str(Svn_name) in r.get('%s:%s-%s' % (svn_name, svn_host,'pkg.get_repo')):
                        nodes[0] = {"area":0,"status":3,"no":0,"parent":[],"label":"%s" % str(Svn_name.svn_name)}
    
                        if nodes[0]['status'] == 3:
                            area_dict1["status"] = 2
                            try:
                                if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.get_repo')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['success'] == "True":
                                    area_dict1["status"] = 3
                                else:
                                    area_dict1["status"] = 1
                            except:
                                area_dict1["status"] = 0
                            area_dict1["area"] = 1
                            area_dict1["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                            area_dict1["label"] = "%s" % str(svn_host)
                            area_dict1["parent"] = [{"parea":0,"pno":0}]
                            svn_list_dict['host'] = svn_host
                            svn_list_dict['name'] = Svn_name
                            svn_list_dict["release_svn"] = Svn_name.svn_no
    
                            """添加检测YUM源存在时间"""
                            try:
                                svn_list_dict['get_repo_time'] = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.get_repo')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['_stamp_localtime']
                            except:
                                svn_list_dict['get_repo_time'] = ''
                            nodes.append(area_dict1)
                            print 'nodes,',nodes[1]['status']
                        else:
                            area_dict1["status"] = 0
    
                        if nodes[1]['status'] == 3:
                            area_dict2["status"] = 2
                            try:
                                if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.upgrade_available')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['success'] == "True":
                                    area_dict2["status"] = 3
                                else:
                                    area_dict2["status"] = 1
                            except:
                                area_dict2["status"] = 2
                            area_dict2["area"] = 2
                            area_dict2["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                            area_dict2["label"] = "%s" % str(svn_host)
                            area_dict2["parent"] = [{"parea":1,"pno":int(area_dict2["no"])}]
    
                            """添加RPM检测更新时间"""
                            try:
                                svn_list_dict['upgrade_available'] = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.upgrade_available')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['_stamp_localtime']
                            except:
                                svn_list_dict['upgrade_available'] = ''
                            nodes.append(area_dict2)
                        else:
                            area_dict2["status"] = 0
    
                        if nodes[2]['status']  == 3:
                            area_dict3["status"] = 2
                            try:
                                if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['success'] == "True":
                                    if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['return']['%s'% svn_name]['old'] != '':
                                        release_old = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['return']['%s'% svn_name]['old'].split('-')[0]
                                    else:
                                        release_old = 0
                                    try:
                                        release_new = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['return']['%s'% svn_name]['new'].split('-')[0]
                                    except:
                                        release_new = ''
                                    if (int(release_old)+1 == int(release_new)) and (int(release_new) == int(Svn_name.svn_no)):
                                        area_dict3["status"] = 3
                                    elif int(release_old) == int(release_new):
                                        area_dict3["status"] = 2
                                    else:
                                        area_dict3["status"] = 1
                                else:
                                    area_dict3["status"] = 1
                            except:
                                area_dict3["status"] = 2
                            area_dict3["area"] = 3
                            area_dict3["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                            area_dict3["label"] = "%s" % str(svn_host)
                            area_dict3["parent"] = [{"parea":2,"pno":int(area_dict3["no"])}]
                            """添加RPM安装时间"""
                            try:
                                svn_list_dict['install'] = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['_stamp_localtime']
    
                                svn_list_dict["release_new"] = release_new
                            except:
                                svn_list_dict['install'] = ''
    
                            nodes.append(area_dict3)
                        else:
                            area_dict3["status"] = 0
                    else:
                        pass
                    svn_list.append(svn_list_dict)
                except Exception as err:
                    print 'Release_status_err:',err
            return render_to_response('myrelease/release_status.html',{'svn_list':svn_list,'nodes':nodes},context_instance=RequestContext(request))
        else:
            return render_to_response('myrelease/release_status.html',context_instance=RequestContext(request))
    

    这段代码大体实现了通过判断pkg.get_repo(验证Yum是否存在),pkg.upgrade_available(验证Yum是否更新),pkg.install(安装)返回的状态,来输出不同的status,前端会根据不同的status,绘制不同的颜色。

    四、效果图:

    Paste_Image.png

    五、前端代码:

    <script type="text/javascript">
        $(function () {
            var chart = new Highcharts.Chart({
                chart: {
                    renderTo: 'container_drawing',
                    events: {
                        load: drawing
                    }
                },
                title: {
                    text: ''
                }
            });
        });
        /* 画图自定义函数 */
        function drawing(){
            // Draw the flow chart
            var ren = this.renderer;
            var rightArrow = ['M', 0, 0, 'L', 100, 0, 'L', 95, 5, 'M', 100, 0, 'L', 95, -5];
            var colors = ['#2570a1','#d71345','#decb00','#1d953f'];//四种状态对应的颜色:未启动,告警,正在运行,完成
    
            // 分割线1
            ren.path(['M', 270, 40, 'L', 270, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
            // 分割线2
            ren.path(['M', 520, 40, 'L', 520, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
            // 分割线3
            ren.path(['M', 770, 40, 'L', 770, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
            // 分割线4
    //        ren.path(['M', 1020, 40, 'L', 1020, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
            // 分割线5
    //        ren.path(['M', 1270, 40, 'L', 1270, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
    
    
    
    
            // 区域标题
    
            ren.label('包构建', 110,50).css({fontWeight: 'bold'}).add();
            ren.label('验证源', 370,50).css({fontWeight: 'bold'}).add();
            ren.label('验证包更新', 610, 50).css({fontWeight: 'bold'}).add();
    //        ren.label('前置命令', 880, 50).css({fontWeight: 'bold'}).add();
            ren.label('项目包安装', 880, 50).css({fontWeight: 'bold'}).add();
    //        ren.label('后置命令', 1380, 50).css({fontWeight: 'bold'}).add();
    
            // 遍历生成图形
            /**
                area:区域编码,值为:0,1,2,null.
                no:节点序号,值为:0,1,...,N,null.
                label:节点内容.
                status:节点状态值为:0为未执行,1为错误,2为执行中,3为执行完毕
                parea:父节点区域编码,值为:0,1,2,null.
                pno:父节点序号,值为:0,1,...,N,null.
            */
    //        var nodes = [{"area":5,"status":2,"no":0,"parent":[{"parea":4,"pno":0}],"label":"md25-qnzs-app-13.youth.cn"},{"area":4,"status":3,"no":0,"parent":[{"parea":3,"pno":0}],"label":"md25-qnzs-app-13.youth.cn"},{"area":3,"status":3,"no":0,"parent":[{"parea":2,"pno":0}],"label":"md25-qnzs-app-13.youth.cn"},{"area":2,"status":3,"no":0,"parent":[{"parea":1,"pno":0},{"parea":1,"pno":1}],"label":"md25-qnzs-app-13.youth.cn"},{"area":1,"status":1,"no":0,"parent":[{"parea":0,"pno":0},{"parea":0,"pno":1},{"parea":0,"pno":3}],"label":"md25-qnzs-app-13.youth.cn"},{"area":1,"status":0,"no":1,"parent":[{"parea":0,"pno":1},{"parea":0,"pno":2}],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":0,"no":0,"parent":[],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":1,"no":1,"parent":[],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":2,"no":2,"parent":[],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":1,"no":3,"parent":[],"label":"md25-qnzs-app-13.youth.cn"}];
            var nodes = {% autoescape off %}{{ nodes}}{% endautoescape %}
            for(var i=0;i<nodes.length;i++){
                var node = nodes[i];
                ren.label(node.label, 30+node.area*250, 80+node.no*50).attr({fill: colors[node.status],stroke: '#f2eada','stroke-width': 2,padding: 5,r: 9,width:220,height:20}).css({color: 'white',fontSize:'xx-small',textAlign:'center',fontWeight: 'bold'}).add().shadow(true);
                for(var j=0;j<node.parent.length;j++){
                    var parent = node.parent[j];
                   ren.path(['M', 30+node.area*250, 75+node.no*50+20, 'L', 2+parent.parea*250+250+10, 75+parent.pno*50+20]).attr({'stroke-width': 2,stroke: '#4169E1'}).translate(0, 0).add();//
                }
            }
        }
    

    相关文章

      网友评论

      本文标题:授之以渔-运维平台发布模块二(Jenkins篇)

      本文链接:https://www.haomeiwen.com/subject/ajffqxtx.html