使用jenkins+sonar进行代码扫描,并发送自定义邮件
jenkins架构
1、一台机器作为jenkins master不进行构建操作,只负责调度其他slave节点执行任务
2、一台slave机器作为执行机器存放从gitlab上拉取的代码,使用sonar-scanner进行代码扫描和使用sonarqube进行页面展示,
步骤
1、在执行机上安装sonarqube和sonar-scanner两个工具
执行机器主要任务有
1、存储代码
2、进行代码扫描
3、根据自己编写的python脚本生成自定义的邮件内容
4、sonar页面展示

下载地址:。。。。。。。
sonarqube安装及配置mysql数据库:http://www.pianshen.com/article/6431255831/
sonar-scanner安装:http://www.pianshen.com/article/1870255571/
2、jenkins master机器配置
2.1 安装插件:SonarQube Scanner for Jenkins

2.2 系统管理》系统设置配置sonarqube
server authentication token中输入sonarqube中生成的token值。

新版本jenkins可能需要先建凭据,再选择而不是直接输入token值,注意凭据的类型为Secret text

2.3 系统管理》全局工具配置sonarqube scanner

3、配置节点(将slave机器注册到master上,以供后续master调用)
3.1 增加节点



3.2 节点配置

3.4 节点启动

4、创建job
4.1 创建自由风格的任务
Restrict where this project can be run(指定此项目在哪个机器上运行),指向我们新建的slave节点机器

拉取代码:

构建步骤新增代码扫描配置
前提:由于要执行sonar.py脚本,所以jenkins所在机器要有python3环境,且安装了pymysql、jinja2,
进入到sonar.py所在目录,执行命令:call E:\Python36\python.exe E:\sonar\sonar_script\sonar.py 项目名

sonar.projectKey=A-yto-steward
sonar.projectName=A网-客户管家
sonar.projectVersion=1.0
sonar.sources=./
sonar.language=java
sonar.sourceEncoding=UTF-
sonar.java.binaries=./
sonar.login=admin
sonar.password=admin
cd ../..
cd sonar_script
call E:\Python36\python.exe E:\sonar\sonar_script\sonar.py A网-客户管家
在执行机如下目录放sonar.py和table.html文件

sonar.py脚本内容
#!/usr/bin/python
# -*- coding:utf-8 -*-
# @Time : 2018/11/20 13:16
# @Author : wnaglihua
# @File : sonar.py import pymysql,os,sys
from jinja2 import FileSystemLoader,Environment def select_project_uuid(project_name):
db = pymysql.connect(host="192.168.207.160", port=3306, user="sonar", passwd="sonar", db="sonar")
cursor = db.cursor()
select_p_uuid="SELECT project_uuid,kee FROM projects WHERE `name`= '%s'" %(project_name)
cursor.execute(select_p_uuid)
result = cursor.fetchone()
p_uuid = result[0]
projectKey = result[1]
db.close()
return(p_uuid, projectKey) def select_total_info(p_uuid):
total_info=[]
# 使用cursor()方法获取操作游标
db = pymysql.connect(host="192.168.207.160", port=3306, user="sonar", passwd="sonar", db="sonar")
cursor = db.cursor() select_p_links = "SELECT text_value FROM project_measures WHERE text_value LIKE 'java=%' and component_uuid=" + "\'" + p_uuid + "\'"
cursor.execute(select_p_links)
p_links = cursor.fetchone()[0].split("=")[1] sql_info = "SELECT count(*) FROM issues WHERE project_uuid='%s' and issue_type =%s"
for leak in [2,3,1]:
search_data = sql_info %(p_uuid, leak)
cursor.execute(search_data)
total_info.append(cursor.fetchone()[0])
db.close()
return p_links,total_info def select_bugs(p_uuid):
bugs=[]
db = pymysql.connect(host="192.168.207.160", port=3306, user="sonar", passwd="sonar", db="sonar")
cursor = db.cursor() sql_info = "SELECT count(*) FROM issues WHERE project_uuid='%s' and issue_type =2 AND severity ='%s'"
for leak in ['BLOCKER','CRITICAL',"MAJOR",'MINOR','INFO']:
search_data=sql_info % (p_uuid,leak)
cursor.execute(search_data)
bugs.append(cursor.fetchone()[0])
db.close()
return bugs def select_leaks(p_uuid):
leaks=[]
db = pymysql.connect(host="192.168.207.160", port=3306, user="sonar", passwd="sonar", db="sonar")
cursor = db.cursor() sql_info = "SELECT count(*) FROM issues WHERE project_uuid='%s' and issue_type =3 AND severity ='%s'"
for leak in ['BLOCKER','CRITICAL',"MAJOR",'MINOR','INFO']:
search_data=sql_info % (p_uuid,leak)
cursor.execute(search_data)
leaks.append(cursor.fetchone()[0])
db.close()
return leaks def select_bad_tastes(p_uuid):
tastes=[]
db = pymysql.connect(host="192.168.207.160", port=3306, user="sonar", passwd="sonar", db="sonar")
cursor = db.cursor() sql_info="SELECT count(*) FROM issues WHERE project_uuid='%s' and issue_type =1 AND severity ='%s'"
for leak in ['BLOCKER','CRITICAL',"MAJOR",'MINOR','INFO']:
search_data=sql_info % (p_uuid,leak)
cursor.execute(search_data)
tastes.append(cursor.fetchone()[0])
return tastes
db.close() curpath = os.getcwd()
table_tem_name="table.html"
def generate_errmsg_table(s_lines="", total_data=[], bugs=[],leaks=[],tastes=[],report_url=""):
env = Environment(loader=FileSystemLoader(curpath, 'utf-8')) # 创建一个包加载器对象
template = env.get_template(table_tem_name)
html_content = (template.render(lins=s_lines,total_data=total_data, bugs=bugs,leaks = leaks,tastes=tastes,report_url=report_url))
fh = open(report_html_path, 'w')
fh.write(html_content)
fh.close() project_name = sys.argv[1]
report_html_path="report\\"+project_name+".html"
p_uuid, projectKey=select_project_uuid(project_name)
s_lines,total_data=select_total_info(p_uuid)
bugs=select_bugs(p_uuid)
leaks=select_leaks(p_uuid)
tastes=select_bad_tastes(p_uuid)
report_url="http://192.168.207.140:9000/dashboard?id=%s" %(projectKey)
generate_errmsg_table(s_lines,total_data,bugs,leaks,tastes,report_url)
table.html脚本内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="GBK">
<body>
<p style="font-weight:bold;">一、总体情况:</p>
<ul>
<li style="font-weight:bold;">整体运行情况:扫描代码行数:<span style="color:blue">{{lins}}</span>, bugs:<span style="color:red">{{total_data[0]}}</span>, 漏洞:<span style="color:red">{{total_data[1]}}</span>, 坏味道:<span style="color:red">{{total_data[2]}}</span></li>
<li style="font-weight:bold;">URL地址:<a style="font-weight:bold;" href={{report_url}} >{{report_url}}</a></li>
</ul>
<p style="font-weight:bold;">二、错误信息详情:</p>
<table border="1" cellpadding="10" width="540" height="120">
<tr ><th></th><th>阻断</th><th>严重</th><th>主要</th><th>次要</th><th>提示</th><th>总数</th></tr>
<tr bgcolor=#ECFFFF><td>bugs</td><td align="center">{{bugs[0]}}</td><td align="center">{{bugs[1]}}</td><td align="center">{{bugs[2]}}</td><td align="center">{{bugs[3]}}</td><td align="center">{{bugs[4]}}</td><td align="center" style="color:red">{{total_data[0]}}</td></tr>
<tr bgcolor=#D2E9FF><td>漏洞</td><td align="center">{{leaks[0]}}</td><td align="center">{{leaks[1]}}</td><td align="center">{{leaks[2]}}</td><td align="center">{{leaks[3]}}</td><td align="center">{{leaks[4]}}</td><td align="center" style="color:red">{{total_data[1]}}</td></tr>
<tr bgcolor=#ECFFFF><td>坏味道</td><td align="center">{{tastes[0]}}</td><td align="center">{{tastes[1]}}</td><td align="center">{{tastes[2]}}</td><td align="center">{{tastes[3]}}</td><td align="center">{{tastes[4]}}</td><td align="center" style="color:red">{{total_data[2]}}</td></tr>
</table>
<br><span style="font-weight:bold;"><b style="color:red">代码扫描度量通过准则:</b></span>
<br><span style="font-size:14px">新覆盖率<%;
<br><span style="font-size:14px">新代码中的重复行密度 (%)>30%;
<br><span style="font-size:14px">新代码可维护率劣于A;
<br><span style="font-size:14px">新代码可靠率劣于A;
<br><span style="font-size:14px">新代码安全率劣于A;
<br></br>
</body>
</html>
邮件配置
安装插件:Email Extension
在系统管理》》系统设置中设置



job中国配置发送邮件

内容选择HTML,打开高级选项

增加触发器,并打开高级选项

输入发送邮箱列表,以英文逗号分隔,和邮件内容,html就是上面步骤生成的

构建完成后会收到如下格式邮件

使用jenkins+sonar进行代码扫描,并发送自定义邮件的更多相关文章
- 持续集成工具之jenkins+sonarqube做代码扫描
上一篇我们主要聊了下代码质量管理平台sonarqube的安装部署以及它的工作方式做了简单的描述和代码扫描演示:回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13 ...
- DEVOPS技术实践_05:sonar静态代码扫描
一.SonarQube静态代码扫描平台 1.1 安装 https://www.sonarqube.org/官网 1.2 下载软件包 https://www.sonarqube.org/download ...
- 03 . Jenkins构建之代码扫描
Sonar简介 Sonar 是一个用于代码质量管理的开放平台.通过插件机制,Sonar可以集成不同的测试工具,代码分析工具,以及持续集成工具.与持续集成工具(例如 Hudson/Jenkins 等)不 ...
- Sonar静态代码扫描环境搭建(Windows10)
一.环境配置: 1.jdk安装及配置 2.MySQL数据库安装----直接调用服务器院端的MySQL数据库,在此基础上创建新的数据库sonar. 数据库的配置如下: 3.sonar官网下载sonar ...
- jenkins集成robot用例并发送自定义报告
slave
- jenkins+sonar发送结果邮件的状态问题修复
在我的这篇博文中:使用jenkins+sonar进行代码扫描,并发送自定义邮件 邮件的配置为默认的$PROJECT_DEFAULT_SUBJECT 所以发送的邮件标题中的状态是jenkins构建的状态 ...
- 代码扫描利器sonarqube
sonar的作用 1.代码质量和安全扫描和分析平台. 2.多维度分析代码:代码量.安全隐患.编写规范隐患.重复度.复杂度.代码增量.测试覆盖率等. 3.支持25+编程语言的代码扫描口分析,包含java ...
- jenkins:集成sonar代码扫描+发送邮件
前提: Jenkins JDK 目录: 1.安装sonar插件:SonarQube Scanner for Jenkins 2.安装SonarQube 3.安装sonar-scanner ++++++ ...
- Jenkins集成openshift容器中进行代码扫描
1.Dockerfile sonarDockerfile: (基础slave镜像参考上篇博文) FROM registry.it.com/openshift/jenkins-slave:latest ...
随机推荐
- PHP基础语法之 三元运算符和其它运算符
三元运算符和其它运算符 此外还有一些特殊的运算符和符号,我们再来进行讲解.可能以后我们需要用到.直线电机选型 符号 说明 $x? 真代码段:假代码段 判断是否为真假 ? 真情况 : 假情况; ``(反 ...
- Mysql查看所有表的数据量
##查看所有表信息 SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'pcms-zgh20190327' ##查看各个表数据量 ...
- php文件上传下载组件
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- Codeforces Round #583
目录 Contest Info Solutions A. Optimal Currency Exchange B. Badges C. Bad Sequence D. Treasure Island ...
- Count on a tree 树上主席树
Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...
- centos7 浏览器(firefox)中文乱码
主要问题在于firefox用了系统没有的字体 百度的方案: 通过yum安装中文字体 (找不到对应的库) 修改firefox的默认字体(尴尬.不知道改哪个才有效) 粗暴的解决方案: 把 windows ...
- cesium地下模式(地表透明)4
这篇博客主要罗列一下解决地下模式(地表透明)的相关资源 1.Cesium的Github仓库地下模式issue 有人提了这个问题,但是cesium官方没有解决这个问题,持续跟踪一下问题说不定哪天官方就解 ...
- Tkinter 之Place布局
一.参数说明 参数 作用 anchor 控制组件在 place 分配的空间中的位置"n", "ne", "e", "se&quo ...
- 制作 ESXI6.7 U盘安装盘并用其安装
工具 UltraISO :软碟通官网下载 EXSI镜像文件:http://ddl6.digiboy.ir/vmware/6.7/VMware-VMvisor-Installer-6.7.0-816 ...
- JSP(工作原理,组成部分,指令标签,动作标签,隐式对象)
目录 JSP JSP 什么是JSP JSP全名为Java Server Pages 中文名叫java服务器页面 它是在传统的网页HTML文件(.htm,.html)中插入Java程序段和JSP标记 后 ...