海云安SAST 静态代码安全检查
1、流水线
import groovy.json.JsonSlurperClassic
// read send result from file
def readJsonFile(def jsonFile){
def jsonString = readFile(file: jsonFile)
echo "${jsonString}"
if ("".equals(jsonString)){
return null
}
def dataObject = new JsonSlurperClassic().parseText(jsonString)
return dataObject
}
//提交本地代码包项目检测
//复制以下代码片段到流水线中,并在测试节点调用该方法
def putLocalProject(def baseUrl, def projectName, def userId, def zipPath, def compileState) {
// upload detect file
sh "curl -k -H \"Content-Type: multipart/form-data\" -F file=@${zipPath} \"${baseUrl}/sca-api/scap/scaProject/myapis/uploadFileByJenkins?userId=${userId}&projectName=${projectName}&compileState=${compileState}\" > ${projectName}-scap-upload.json"
projectName = URLEncoder.encode(projectName)
def dataPutLocal = readJsonFile("${projectName}-scap-upload.json")
if (dataPutLocal == null || dataPutLocal.resultInfo == null){
return -1
}
return dataPutLocal.resultInfo.projectVersionId
}
//获取项目检测状态
//复制以下代码片段到流水线中,并在测试节点调用该方法
def getScanResult(def baseUrl, def versionId, def userId, def score){
def jsonStr = "{\"userId\": \"${userId}\", \"projectVersionId\": \"${versionId}\"}"
sh "curl -H \"Content-Type:application/json\" -k ${baseUrl}/sca-api/scap/scaProject/myapis/getScanResult -d '${jsonStr}' > ${versionId}-scap-result.json"
def dataResult = readJsonFile("${versionId}-scap-result.json")
if (dataResult != null && dataResult.resultInfo != null){
def status = dataResult.resultInfo.status
if (status == 8 || status == 2 || status == 3){
echo "正在检测"
return 1
}
if (status == 5){
echo "检测失败"
return -1
}
if (status == 9){
echo "取消检测"
return -1
}
}else{
echo "任务不存在"
return -1
}
echo "正在生成报告"
def jsonStrReport = "{\"userId\": \"${userId}\", \"projectVersionId\": \"${versionId}\", \"reportFileType\": \"2\"}"
sh "curl -H \"Content-Type:application/json\" -k ${baseUrl}/sca-api/scap/scaProject/myapis/reportExport -d '${jsonStrReport}' > ${versionId}-scap-report.json"
def reportResult = readJsonFile("${versionId}-scap-report.json")
if (reportResult != null && reportResult.reportUrl != null){
def reportUrl = reportResult.reportUrl
echo "生成成功,开始下载"
sh "curl -k -o scap_report.pdf ${reportUrl}"
def defaultScore = score
def nowScore = dataResult.resultInfo.score
if (nowScore - defaultScore < 0){
echo "${dataResult.resultInfo.score} 低于阈值 ${score}"
return -2
}
return 0
}
echo "导出失败"
return 0
}
pipeline{
agent{
node{
label 'kems-10.202.61.111'
}
}
environment{
PROJECT_NAME="$JOB_NAME"
PROJECT_WORKSPACE="$WORKSPACE"
}
stages{
stage('Init'){
steps{
dir("$PROJECT_WORKSPACE"){
script{
echo "清理工作空间"
sh "rm -rf *"
}
}
}
}
stage('Checkout'){
steps{
dir("$PROJECT_WORKSPACE"){
//SVN拉取代码
checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'b3519cbb-ac27-4962-a8c4-dcb2daa79db2', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'https://10.200.0.2/ZHCS/kems/branches/v3.4.0/server/kems-project']], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']])
//Git拉取代码
//git branch: 'develop', credentialsId: 'xx', url: 'http://xxx.git'
}
}
}
stage('Build'){
steps{
dir("$PROJECT_WORKSPACE"){
//编译构建,根据编译命令实际调整
sh "mvn clean install -Dmaven.test.skip=true"
//sh "mvn package -T 1C -Dmaven.test.skip=true -Dmaven.compile.fork=true"
//sh "mvn clean package -Dmaven.test.skip=true"
}
}
}
stage('CodeScan'){
steps{
dir("$PROJECT_WORKSPACE"){
script{
//zip打包
def baseUrl = "https://10.210.5.46:3443/oscap"
def projectName = "$JOB_NAME"
//***useId需替换为自己的***
def userId = "1698613944978575361"
// 是否需要编译 1是 2否,针对编译型语言如java需要源码配合编译后文件及相关依赖进行检测,若所传文件已包含所需内容可选择'否'跳过编译阶段以节省检测时间
def compileState = 2
// 是否轮询等待任务完成 1是 2否
def waitFlag = 1
// 设置阈值分数 低于该分数则中断构建过程 0为不中断
def score = 80
// 是否在分数低于阈值时中断后续构建过程 1是 2否
def stageFlag = 2
// 是否在分数低于阈值时继续导出报告 1是 2否
def flag = 1
sh "zip -r ${projectName}.zip *"
def zipPath = "${WORKSPACE}/${projectName}.zip"
def projectVersionId = putLocalProject(baseUrl, projectName, userId, zipPath, compileState)
if (waitFlag == 1){
echo "创建任务成功,等待检测完成,一分钟轮询一次"
}
else{
echo "创建任务成功,请在平台上查看该任务!"
return
}
// return 中断当前 sh "exit 255" 退出
if (projectVersionId != -1){
while(true){
def status = getScanResult("${baseUrl}", "${projectVersionId}", "${userId}", score)
if (status == 0){
// 检测成功
break
}
else if (status == -1){
echo "任务检测失败"
return
}
else if (status == -2){
flag = 2
// 分数太低
// return 中断当前 sh "exit 255" 退出
break
}
sleep 60
}
}
else{
// return 中断当前 sh "exit 255" 退出
// 创建检测任务失败
}
echo "任务检测完成"
archiveArtifacts 'scap_report.pdf'
// 如果分数低于阈值 中断后续构建过程
if (stageFlag == 1 && flag == 2){
sh "exit 255"
}
}
}
}
}
}
}
参数说明:
userId:个人设置-用户编号复制