案例阐明
- 模仿场景:模仿 common、user、大数据代码扫描
- 根本流程:下载代码 -> 执行扫描命令
- 指标:用最简略的形式演示残缺模板性能
实现思路
分三步:
- 编写 project.yaml:形容我的项目、运行环境、编排模板、环境配置等信息
- 定义模块:定义扫描代码的执行脚本
- 执行:结构申请参数和执行
利用模板的所有配置文件如下图:
编写 project.yaml
蕴含内容如图
project.yaml
内容(编排模板另建文件编写,外围且较简单
):
kind: Project
apiVersion: api/v1
metadata:
name: sonar # 项目名称
spec:
engine:
sonar: | # 定义编排模板(个别较简单且外围,因而另建文件治理)%{readText "_projects/sonar.engine.yaml" | indent 6}%
default: # 设置全局的默认属性
env:
info:
sonar: # 设置所有环境的默认 sonar 地址和 token
url: http://xxx:9090
token: xxx
envs:
prod:
code:
branch: master # 按环境设置默认分支
mvn:
profile: prod # maven 治理代码 设置 profile 为 prod
编排模板 (_projects/sonar.engine.yaml
) 内容:
first: &first # 扫描的第一局部代码
sonar:
- name: common
second: &second # 扫描的第二局部代码
sonar:
- name: user
metadata:
annotations:
notify-types: "group,personal"
template: 'sonar:latest'
spec:
global:
workflow: # 定义工作流信息
parallelism: 256 # 并发工作数
ttlStrategy:
secondsAfterCompletion: 86400 # 完结工作流保留 1 天工夫
secondsAfterSuccess: 86400 # 完结工作流保留 1 天工夫
secondsAfterFailure: 172800 # 失败工作流保留 2 天工夫
kube: # 定义 k8s 的运行环境信息
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: app
operator: In
values:
- ops
tolerations:
- key: cattle.io/os
operator: Equal
value: linux
effect: "NoSchedule"
- key: app
operator: Equal
value: ops
effect: "NoSchedule"
@{- $part := $.params.annotations.part}@
stages:
- name: "sonar"
desc: "代码品质扫描"
modules:
@{- if eq $part "first"}@
<<: *first # 当代码仓库数量很多,而资源又无限时离开扫描
@{- else if eq $part "second"}@
<<: *second # 当代码仓库数量很多,而资源又无限时离开扫描
@{- else if eq $part "bigdata"}@ # 分类扫描:为大数据独立构建工作流
sonar:
- name: bigdata
@{- end}@
定义模块
蕴含内容如图:
模板内容如下(执行脚本
较简单,也另建文件治理):
sonar:
__global__: # 模块层的全局配置
execTmpl: |
%{readText "code/sca.yaml" | indent 34}%
default: # 模块级的默认配置
type: git # 类型都为 git
config: "" # 示意不须要生成配置文件
common:
labels:
package: true # 示意公共库
settings:
repo: http://xxx/common.git
mvn:
api: # 只上传 jar 包 不打包和构建镜像
dir: ""
sonar:
exclusions: 'src/main/java/xxx/protobuf/**' # sonar 扫描排除 pb 代码
user:
labels:
role: user # 属于用户核心;默认(和不填)为公共模块,服务于所有部门;反对多个归属
settings:
repo: http://xxx/user.git
mvn:
api:
dir: user-api
service:
dir: user-service
bigdata:
labels:
role: bigdata # 属于大数据中心;默认(和不填)为公共模块,服务于所有部门;反对多个归属
settings:
repo: http://xxx/bigdata.git
branch: dev
mvn:
api:
dir: flink-stream
sonar:
exclusions: 'src/main/**/proto/**'
执行脚本模板(code/sca.yaml
)如下:
# 分两步:# 1. 下载代码
# 2. 扫描代码
@{- $env := .env -}@
@{- $repoName := repoName .settings.repo}@
@{- $parent := .}@
- name: git
image: busybox
command: [/bin/sh, -c]
args:
- |
echo 下载代码 @{.settings.repo}@ branch:@{or .settings.tag .settings.branch (render $env.code.branch .) }@
@{- range $type,$val := .settings.mvn}@
- name: mvn-sast-@{$type}@
depends: [git]
image: busybox
command: [/bin/sh, -c]
args:
- |
echo 代码扫描
@{- $projName := $repoName}@
@{- if $val.dir}@
@{- $projName = concat $projName ":" $val.dir}@
@{- end}@
@{- $projName = replace $projName "/" ":" -1}@
echo 'mvn clean package sonar:sonar -DskipTests -U -P @{$env.mvn.profile}@ \
@{- if (or $parent.settings.sonar.exclusions "") }@
-Dsonar.exclusions=@{$parent.settings.sonar.exclusions}@ \
@{- end}@
-Dsonar.projectKey=SAST:@{$projName}@ \
-Dsonar.projectName=SAST:@{$projName}@ \
-Dsonar.host.url=@{$env.info.sonar.url}@ \
-Dsonar.login=@{$env.info.sonar.token}@'
@{- end}@
执行
分两步:
- yaml 定义参数
- cli 执行
残缺的执行脚本 (Makefile
) 如下:
server=http://localhost:8888
# OPS_USER 需设置环境变量,eg:export OPS_USER=xxx
apply-sonar:
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/project.yaml
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/definitions/main.yaml
#扫描 common 代码
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-common.yaml
#扫描 user 代码
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-user.yaml
#扫描大数据代码
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-bigdata.yaml
扫描第一局部代码(common)
参数定义:
kind: Engine
apiVersion: api/v1
metadata:
name: sonar-1 # 编排名称:用于编排工作分类
cron: "0 20 * * *" # 定时工作:每天晚上 8 点执行一次
envs:
- prod # 指定环境:应用环境定义的属性
engine: sonar # 指定我的项目编排的模板:利用 `project.spec.engine.sonar` 编排模板
annotations: # 扩大属性:用于编排模板渲染
part: first
branch: master
执行
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-common.yaml
扫描第二局部代码(user)
参数定义:
kind: Engine
apiVersion: api/v1
metadata:
name: sonar-2 # 编排名称:用于编排工作分类
cron: "0 20 * * *" # 定时工作:每天晚上 8 点执行一次
envs:
- prod # 指定环境:应用环境定义的属性
engine: sonar # 指定我的项目编排的模板:利用 `project.spec.engine.sonar` 编排模板
annotations: # 扩大属性:用于编排模板渲染
part: second
branch: master
执行
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-user.yaml
扫描大数据代码(bigdata)
参数定义:
kind: Engine
apiVersion: api/v1
metadata:
name: sonar-bigdata # 编排名称:用于编排工作分类
cron: "0 20 * * *" # 定时工作:每天晚上 8 点执行一次
envs:
- prod # 指定环境:应用环境定义的属性
engine: sonar # 指定我的项目编排的模板:利用 `project.spec.engine.sonar` 编排模板
annotations: # 扩大属性:用于编排模板渲染
part: bigdata
branch: dev
执行
ops apply -p sonar -s ${server} -u ${OPS_USER} -f sonar/engines/params-bigdata.yaml
成果展现
扫描第一局部代码(common)
工作流工作
工作流日志 1(下载代码):
工作流日志 2(代码扫描):
扫描第二局部代码(user)
工作流工作
工作流日志 1(下载代码):
工作流日志 2(代码扫描):
扫描大数据代码(bigdata)
工作流工作(有 api
和service
两个个代码扫描工作)
工作流日志 1(下载代码):
工作流日志 2(扫描代码api
):
工作流日志 2(扫描代码service
):
结语
只需写 模板文件 和配置文件 就能够构建本人的工作流,保障了 <font style=”color:red;font-weight:bold”> 良好的扩展性 </font>。
请 <font style=”color:red;font-weight:bold”> 同学 </font> 关注下😉,我专一云原生 DevOps 落地,将按段公布上述能力的落地计划。
本文由 mdnice 多平台公布