Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

21
app/admin/main/apm/BUILD Normal file
View File

@@ -0,0 +1,21 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/apm/cmd:all-srcs",
"//app/admin/main/apm/conf:all-srcs",
"//app/admin/main/apm/dao:all-srcs",
"//app/admin/main/apm/http:all-srcs",
"//app/admin/main/apm/model:all-srcs",
"//app/admin/main/apm/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,549 @@
### apm-admin
##### Version 1.23.7
> 1. 切换canal更新接口为/home/config/update
##### Version 1.23.6
> 1. 增加databus获取消费者地址接口
##### Version 1.23.5
> 1. go-common/library包加入ut检验
##### Version 1.23.4
> 1. 去掉 ut_app log 中 has_ut 字段.
##### Version 1.23.3
> 1. 修改alarm接口中百分比字段的默认值为0
> 2. 修改创建group时的百分比字段默认值为80
##### Version 1.23.2
> 1. 优化和修正因增加library单测的ut逻辑
##### Version 1.23.1
> 1. 批量修改告警功能
##### Version 1.23.0
> 1.unit_test.sh 大重构.
> 2.增加对整个项目覆盖率的统计.
> 3.现在所有涉及到ut_pkganls表都有过滤项目逻辑(方便以后统计逻辑变更).
##### Version 1.22.1
> 1.修改gitface token
##### Version 1.22.0
> 1.删除canal申请auth
##### Version 1.21.0
> 1.添加databus topic查询
##### Version 1.20.4
> 1.告警接口延迟
##### Version 1.20.3
> 1.去除部分冗余代码加入group批量添加告警接口
##### Version 1.20.2
> 1.add unlock.
##### Version 1.20.1
> 1.增加canal申请审核微信通知
> 2.增加需求建议微信通知
##### Version 1.20.0
> 1.优化覆盖率计算方式.
##### Version 1.19.3
> 1.databus告警接口添加project
##### Version 1.19.2
> 1.ut.Upload 接口增加耗时日志.
##### Version 1.19.1
> 1.多语言错误码后台
##### Version 1.18.8
> 1.增加rank排名变化显示.
> 2.增加ut_app owner更新逻辑
##### Version 1.18.7
> 1.upload date_file 不为空.
##### Version 1.18.6
> 1.ut上传接口增加ut_app表处理
##### Version 1.18.5
> 1.增加redis配置
> 2.ut 新增周五群发周刊消息
##### Version 1.18.4
> 1.reply-feed透传
##### Version 1.18.3
> 1.fix canal infoc字段
##### Version 1.18.2
> 1.fix canal 编辑project&leader字段被覆盖
##### Version 1.18.1
> 1.databus告警
##### Version 1.17.3
> 1.userAuth接口增加返回头像
> 2.ut包覆盖率改为用包内文件计算
##### Version 1.17.2
> 1.增加dashboard项目负责人视图
##### Version 1.17.1
> 1.增加项目接入ut情况的统计
##### Version 1.16.13
> 1.修复utRank endtime格式
##### Version 1.16.12
> 1.添加monkey
##### Version 1.16.11
> 1.添加一个接口
##### Version 1.16.10
> 1.同步code码信息获取线上信息改为内部接口调用
##### Version 1.16.9
> 1.同步code码信息
##### Version 1.16.8
> 1.修复canal databus group重复返回错误提示
##### Version 1.16.7
> 1.优化UT列表和历史列表接口项目覆盖率计算方式
> 2.修复UT发送微信消息超过2048字节被截断问题
##### Version 1.16.6
> 1.修复group_concat函数默认长度为1024导致数据被截断问题
> 2.处理调用cmd.Start()导致产生僵尸进程的问题
##### Version 1.16.5
> 1.go command add cmd.Wait().
> 2.commented activeWarning func code.
##### Version 1.16.4
> 1.ut增加原始覆盖数据文件处理
> 2.ut企业微信和Git报告增加行数相关信息
> 3.修复databus生产group申请冲突问题
##### Version 1.16.3
> 1.ecode增加告警级别和繁体信息字段
##### Version 1.16.2
> 1.重写monitor模块
> 2.修复upload接口未关闭http链接问题
##### Version 1.16.1
> 1.修改canal scan databus&infoc为空返回null
##### Version 1.16.0
> 1.添加运维报警接口
##### Version 1.15.15
> 1.ut rank增加抛物线时间衰减因子统计.
##### Version 1.15.14
> 1.ut曲线图修复按hour统计数据问题
> 2.补充canal dao层测试用例
> 3.canal修复project字段编辑被覆盖
##### Version 1.15.13
> 1.dashboard 个人排行榜增加排位统计.
> 2.解除openView默认权限改为需授权状态
##### Version 1.15.12
> 1.排行榜威尔逊区间算法增加牛顿冷却因子.
##### Version 1.15.11
> 1.ut general commit排序功能修复
> 2.ut upload接口增加author参数
> 3.ut commit context with background.
> 4.修正ut数据对比若干问题
##### Version 1.15.10
> 1.utRank排名算法优化
> 2.ut下线发送Bottom 10微信群消息的功能
##### Version 1.15.9
> 1.修复pprof返回的图片地址参数错误的问题
> 2.新增性能管理权限,去除/discovery权限验证
> 3.修复ut微信报告中用户名取值问题
##### Version 1.15.8
> 1.ut dashboard 返回baseline
> 2.ut增加发送企业微信消息功能
##### Version 1.15.7
> 1.ut dashboard 新增最近10条个人历史commit记录接口
> 2.增加ut聚合commit概要信息
> 3.ut shell脚本magic执行顺序修改及upload失败直接返回错误不做check
##### Version 1.15.6
> 1.优化utRank排名实现方式
##### Version 1.15.5
> 1.告警抓取的信息存储至db
> 2.新增告警信息查询接口
##### Version 1.15.4
> 1.修复 format 时乱序的问题
##### Version 1.15.3
> 1.修复git评论ut简报包链接跳转问题
> 2.修复ut检查接口commit_id不存在返回不报错的问题
> 3.ut dashboard 新增个人全量排名
##### Version 1.15.2
> 1.优化dashboard时间顺序展示
##### Version 1.15.1
> 1.删除存储告警信息
> 2.新增根据告警信息实时抓取内存图和性能图
##### Version 1.15.0
> 1.ut dashboard 增加个人质量聚合数据
##### Version 1.14.17
> 1.增加ut个人dashboard文件展示功能
> 2.更改SAGAReaport功能自动调用gitlab接口添加留言
> 3.修复dao层ut用例
##### Version 1.14.16
> 1.增加拉取gitlab头像的token
##### Version 1.14.15
> 1.单元测试tyrant接口改名为check
##### Version 1.14.14
> 1.修复canal monitor_period为空bug
> 2.优化canal 历史代码
##### Version 1.14.13
> 1.添加rank排行头像
##### Version 1.14.12
> 1.添加存储告警数据接口
##### Version 1.14.11
> 1.修复canal编辑字段缺失
##### Version 1.14.10
> 1.修复monitor采集databus数据类型转换的错误bug
##### Version 1.14.9
> 1.单元测试merge/set接口改为接收webhook参数形式
##### Version 1.14.8
> 1.增加单元测试统计数据的排行utRank
##### Version 1.14.8
> 1.ut添加当前用户最近10次提交记录
> 2.upload开启一个事物存储表数据
##### Version 1.14.7
> 1.增加一批用户默认权限
##### Version 1.14.6
> 1.notify添加机房选项
##### Version 1.14.5
> 1.canal databus信息增加从app旧表获取key&secret
> 2.canal config信息增加monitor_period字段
> 3.canal check master接口改为post
> 4.canal DB增加infoc部分
##### Version 1.14.4
> 1.ut/check接口去掉增长率的判断
##### Version 1.14.3
> 1.新增监控rpc数据
> 2.修复获取在线人数统计
> 3.扩展monitor/prometheus 接口
##### Version 1.14.2
> 1.优化查询历史ut_detail sql
##### Version 1.14.1
> 1.增加pprof火焰图
##### Version 1.13.13
> 1.新增monitor监控数据查询接口
##### Version 1.13.12
> 1.ut/check 取历史最大值比较
##### Version 1.13.11
> 1.canal 增加databus auth表判断
##### Version 1.14.0
> 1.重构 ut 相关所有接口.
##### Version 1.13.10
> 1.ut/upload 强制更新默认值
##### Version 1.13.9
> 1.ut/check 添加日志
> 2.增加通过率判断
##### Version 1.13.8
> 1.ut/check 去除多余判断
##### Version 1.13.7
> 1.add user 需求module
##### Version 1.13.6
> 1.ut/check接口修改默认值
##### Version 1.13.5
> 1.ut单元测试添加达标检测接口
##### Version 1.13.4
> 1.open鉴权管理透传
##### Version 1.13.3
> 1.discovery列表接口变更
##### Version 1.13.2
> dapper 添加独立 Host
##### Version 1.13.1
> 1.添加monitor监控定时任务
> 2.bfs upload接口返回错误信息
##### Version 1.13.0
> 1.增加monitor数据监控收集模块
##### Version 1.12.0
> 1.增加需求与建议模块
##### Version 1.11.8
> 1.增加ut baseline接口参数配置化
> 2.canal审核接口增加force强制推送
> 3.ut列表返回三个月之内数据
> 4.utlist,historycommit增加mtime字段
##### Version 1.11.7
> 1.ut detail 接口pkg数据去重
> 2.修改upload返回sven地址
> 3.增加unittest.sh对pkg下是否存在go文件的判断
##### Version 1.11.6
> 1.ut增加history commit及bfs proxy接口
##### Version 1.11.5
> 1.upload接口增加TestResult结果过滤
##### Version 1.11.4
> 1.canal process 增加对master_info 表中addr的检验
##### Version 1.11.3
> 1.上传bfs接口删除二级目录/ut/
##### Version 1.11.2
> 1.上传bfs接口添加二级目录/ut/
##### Version 1.11.1
> 1.heap接口创建文件改成串行
##### Version 1.11.0
> 1.bm bind返回修改
> 2.pprof heap添加独立接口
##### Version 1.10.11
> 1.canal修改config配置参数,server_id,active
##### Version 1.10.10
> 1.pprof以主机名为纬度存图
##### Version 1.10.9
> 1.notify申请支持重命名功能
> 2.对pprof增加对内存的数据抓取
##### Version 1.10.8
> 1.增加canal申请对user/pwd进行checkmaster检查.
> 2.canal config table字段增加primarykey,omitfield
##### Version 1.10.7
> 1.修复notify编辑的错误
> 2.修复读取svg图的权限错误
> 3.修复用户模块和权限编辑功能
> 4.修复一些bm框架接收数据的问题
##### Version 1.10.6
> 1.修复required 错误
##### Version 1.10.5
> 1.增加canalsvenCo配置文件信息
##### Version 1.10.4
> 1.pprof命令拼错的bug修改
##### Version 1.10.3
> 1.parse修改为bm框架的方法
##### Version 1.10.2
> 1.pprof的go路径配置
##### Version 1.10.0
> 1.增加cacheview权限
> 2.抽离permit
##### Version 1.9.1
> 1.pprof功能更新加入cpu和内存图
> 2.平台管理透传
##### Version 1.9.0
> 1.新增ut模块用户查询saga执行的单测结果
> 2.新增upload文件上传接口提供给saga调用将单测执行的结果存储至bfs
##### Version 1.8.3
> 1.增加token参数调用配置中心canal接口
##### Version 1.8.2
> 1.fix config update bug
##### Version 1.8.1
> 1.pprof功能
##### Version 1.8.0
> 1.canal 新增申请并同步至配置中心接口 apply/config
> 2.canal scan接口增加管理员编辑获取user/pwd
> 3.canal list接口增加status/operator返回字段
> 4.canal 新增返回所有已存在canal addr信息接口addrall
> 5.canal 新增canal编辑申请接口config/edit
> 6.canal 新增apply申请列表 apply
> 7.canal 新增process审核接口 process
##### Version 1.7.5
> 1.topic修改集群时在新的kafka自动创建topic
##### Version 1.7.7
> 1.修复事务的bug
##### Version 1.7.5
> 1.topic修改集群时在新的kafka自动创建topic
##### Version 1.7.4
> 1.databus加入按时间和位置设置offset
> 2.修正groups接口operation字段的返回值
> 3.修正创建topic时的一个kafka集群判断bug
> 4.discovery的下拉菜单权限开放
##### Version 1.7.3
> 1.user申请时非线上环境过滤配置中心权限申请
> 2.databus的Group申请编辑审核中支持新增和修改topic相关功能
##### Version 1.7.2
> 1.user新增权限申请修改接口
##### Version 1.7.0
> 1.user新增申请操作权限审核权限等功能
##### Version 1.6.0
> 1.bm框架
##### Version 1.5.3
> 1.修复查看canal详情获取错误bug
> 2.env环境读取本地环境变量
> 3.过滤敏感信息
##### Version 1.5.2
> 1.discovery获取服务列表接口变更
##### Version 1.5.1
> 1.group差值partition排序
> 2.discovery的polling接口聚合
> 3.topic列表查询修改cluster非必须
> 4.tree/nodes服务树权限去重
##### Version 1.5.0
> 1.添加canal/delete接口删除canal配置
> 2.添加canal/scan接口查询canal详情
##### Version 1.4.2
> 1.fix notify bug
##### Version 1.4.1
> 1.添加kafka创建topic
> 2.修复申请消费修改project但group没重新生成的bug
> 3.去cluster
##### Version 1.4.0
> 1.添加notify申请编辑
##### Version 1.3.7
> 1.修正group申请的一系列bug
##### Version 1.3.6
> 1.修正databus申请有重复无法创建的bug
> 2.修改集群的时候同时也要修改老表的cluster
##### Version 1.3.5
> 1.sven权限变更
##### Version 1.3.4
> 1.databus group申请及审核功能
##### Version 1.3.3
> 1.databus group设为kafka最老记录
> 2.添加所有group 分页diff接口
##### Version 1.3.2
> 1.log日志接入
> 2.apm-admin迁到main下
##### Version 1.3.1
> 1.修复canal不能编辑leader和cluster的问题
##### Version 1.3.0
> 1.增加鉴权功能
##### Version 1.2.9
> 1.修复group的重命名权限
##### Version 1.2.8
> 1.databus的app/edit的bug修正
##### Version 1.2.7
> 1.databus的offset差值规则修改
##### Version 1.2.7
> 1.app鉴权接口
##### Version 1.2.6
> 1.databus,group修改增加备注字段
> 2.user/auth接口返回格式变更
> 3.修复新加group的告警默认为0的bug
> 4.服务树接口更换
> 5.discovery的nodes接口特殊规则
##### Version 1.2.5
> 1.databus告警,group展示告警规则,修复了alarm接口连删除数据也返回的错误
##### Version 1.2.4
> 1.databuscanal告警功能codes改为ecode
##### Version 1.2.3
> 1.discovery透传接口增加appids接口
##### Version 1.2.2
> 1.databus新增功能删除group重命名offset等
##### Version 1.2.1
> 1.cannl更优雅的写法auth方法变更
##### Version 1.2.0
> 1.增加配置中心菜单权限
##### Version 1.1.9
> 1.增加group判断是否已存在
##### Version 1.1.8
> 1.databus告警需要的节点接口
##### Version 1.1.7
> 1.项目组重复增加group2
##### Version 1.1.6
> 1.修复服务树接口
##### Version 1.1.5
> 1.新增canal增改接口
##### Version 1.1.4
> 1.codes新接口
##### Version 1.1.3
> 1.添加dapper接口支持
##### Version 1.1.2
> 1.修复apm permit
##### Version 1.1.1
> 1.过滤group的projects
##### Version 1.1.0
> 1.用户权限限制
##### Version 1.0.0
> 1.用户管理
> 2.databus管理

View File

@@ -0,0 +1,19 @@
# Owner
haoguanwei
lintanghui
chenjianrong
chenzhihui
linli
# Author
haoguanwei
linli
lintanghui
chenjianrong
chengxing
hedan
# Reviewer
haoguanwei
linli
chenjianrong

21
app/admin/main/apm/OWNERS Normal file
View File

@@ -0,0 +1,21 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- chenjianrong
- chenzhihui
- haoguanwei
- linli
- lintanghui
labels:
- admin
- admin/main/apm
- main
options:
no_parent_owners: true
reviewers:
- chengxing
- chenjianrong
- haoguanwei
- hedan
- linli
- lintanghui

View File

@@ -0,0 +1,11 @@
#### apm-admin
##### 项目简介
> 1.提供主站APM相关后台管理功能
##### 编译环境
> 请只用golang v1.8.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common
> 2.kafka

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["apm-admin-test.toml"],
importpath = "go-common/app/admin/main/apm/cmd",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/http:go_default_library",
"//app/admin/main/apm/service:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/os/signal:go_default_library",
"//library/queue/databus/report:go_default_library",
"//library/syscall:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,175 @@
env = "dev"
apptoken = "a999eb3371de0a7be87d92823be36817"
[utBaseLine]
coverage = 60
passrate = 100
superman = ["haoguanwei","linli"]
[pprof]
dir = "/data/pprof"
#goPath = "/usr/local/go/bin/go"
[databusConfig]
partitions = 3
factor = 1
[tree]
platformID = "2F3b8fDVGlMnj8aCDlMaW"
msmPlatformID = "VH7rmAQ+9)T/tLXdCAwQ.X*evJFxWWjKA7)xYeG]p]UB{4jGY,rBBr"
[host]
apiCo = "http://172.22.33.185:7171"
svenCo = "http://fat1-sven.bilibili.co"
managerCo = "http://uat-manager.bilibili.co"
dapperCo = "http://172.16.38.143:6193"
[canal]
canalsvenCo = "http://fat1-sven.bilibili.co"
reviewer = ["fengshanshan"]
[discovery]
api = ["172.22.33.185:7171","172.22.33.174:7171","172.22.33.183:7171"]
[log]
stdout = true
# dir = "/data/log/apm-admin"
# [log.agent]
# family = "apm-manager"
# taskID = "000069"
# proto = "unixgram"
# addr = "/var/run/lancer/collector.sock"
# chan = 10240
[httpClient]
key = "3c4e41f926e51656"
secret = "26a2095b60c24154521d24ae62b885bb"
dial = "3s"
timeout = "10s"
keepAlive = "60s"
[orm]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_apm_v2?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
#dsn = "root:root@tcp(127.0.0.1:3306)/bilibili_apm_v2?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 1
idleTimeout = "4h"
[ormdatabus]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_databus_v2?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 1
idleTimeout = "4h"
[ormcanal]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_canal?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 1
idleTimeout = "4h"
[ormapmmonitor]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_apm?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 1
idleTimeout = "4h"
[kafka]
"test_kafka_9092-266" = { brokers = ["172.16.38.154:9192"] }
[auth]
managerHost = "http://uat-manager.bilibili.co"
dashboardHost = "http://dashboard-mng.bilibili.co"
dashboardCaller = "sven"
[auth.DsHTTPClient]
key = "sven"
secret = "a9564ebc3289b7a14551baf8ad5ec60a"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
[auth.DsHTTPClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[auth.MaHTTPClient]
key = "f6433799dbd88751"
secret = "36f8ddb1806207fe07013ab6a77a3935"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
[auth.MaHTTPClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[auth.session]
sessionIDLength = 32
cookieLifeTime = 1800
cookieName = "sven-apm"
domain = ".bilibili.co"
[auth.session.Memcache]
name = "go-business/auth"
proto = "tcp"
addr = "172.16.33.54:11211"
active = 10
idle = 10
dialTimeout = "10ms"
readTimeout = "10ms"
writeTimeout = "10ms"
idleTimeout = "80s"
[bfs]
addr = "http://bfs.bilibili.co"
bucket = "test"
key = "221bce6492eba70f"
secret = "6eb80603e85842542f9736eb13b7e3"
# 上传文件大小限制为1M
maxFileSize = 1048576
[prometheus]
url = "http://merak.bilibili.co/"
key = "71f079db59672ecec5b8d6f252c4b59ab2a8a227mainsite@bilibili.com"
secret = "37ba757817b4e9c45c7e97f6ed5eee4e1c7bac52"
[apps]
name = ["main.account.member-service", "main.account.vip-service"]
max = 1000
[broadcast]
tencent = ["tx-bj-pf-broadcast-01","tx-bj-pf-broadcast-02","tx-bj-pf-broadcast-03","tx-bj-pf-broadcast-04","tx-bj-pf-broadcast-05",
"tx-bj-pf-broadcast-06","tx-bj-pf-broadcast-07",
"tx-gz-pf-broadcast-001","tx-gz-pf-broadcast-002","tx-gz-pf-broadcast-003","tx-gz-pf-broadcast-004","tx-gz-pf-broadcast-005",
"tx-gz-pf-broadcast-006","tx-gz-pf-broadcast-007",
]
kingsoft = ["ks-sh2-pf-dmcmt-pm-01", "ks-sh2-pf-dmcmt-pm-02",
"ks-pf-broadcast-001","ks-pf-broadcast-002","ks-pf-broadcast-003","ks-pf-broadcast-004","ks-pf-broadcast-005",]
[cron]
crontab = "0 0 23 * * *"
crontabRepo = "0 0 19 * * *"
[wechat]
users = ["chengxing"]
chatid = "utbroadcasttest"
[gitlab]
api = "http://git.bilibili.co/api/v4"
# personal token
token= "UfzT-r-dhEXpGopxYFYW"
[redis]
name = "apm-admin/apm"
proto = "tcp"
addr = "172.22.33.117:6816"
idle = 2
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
expireTime = "1h"

View File

@@ -0,0 +1,57 @@
package main
import (
"flag"
"os"
"time"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/http"
"go-common/app/admin/main/apm/service"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/os/signal"
"go-common/library/queue/databus/report"
"go-common/library/syscall"
)
var (
s *service.Service
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
ecode.Init(conf.Conf.Ecode)
log.Init(conf.Conf.Log)
defer log.Close()
report.InitManager(conf.Conf.ManagerReport)
// service init
s = service.New(conf.Conf)
http.Init(conf.Conf, s)
log.Info("apm-admin start")
signalHandler()
}
func signalHandler() {
var (
ch = make(chan os.Signal, 1)
)
signal.Notify(ch, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
si := <-ch
log.Info("get a signal %s, stop the apm-admin process", si.String())
switch si {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
s.Close()
time.Sleep(time.Second)
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,39 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/admin/main/apm/conf",
tags = ["automanaged"],
deps = [
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/queue/databus:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,237 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/orm"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/queue/databus"
xtime "go-common/library/time"
"github.com/BurntSushi/toml"
)
var (
// config
confPath string
client *conf.Client
// Conf global config.
Conf = &Config{}
)
// Config def.
type Config struct {
// base
Superman []string
AppToken string
//utBaseLine
UTBaseLine *UTBaseLine
// Host
Host *Host
// Canal
Canal *Canal
// log
Log *log.Config
// ecode
Ecode *ecode.Config
// client
HTTPClient *bm.ClientConfig
// db
ORM *orm.Config
// db databus
ORMDatabus *orm.Config
// db canal
ORMCanal *orm.Config
// kafka
Kafka map[string]*Kafka
// identify
Auth *permit.Config
// discovery
Discovery *Discovery
// tree
Tree *Tree
// databus kafka create topic config
DatabusConfig *Databus
//BM
BM *bm.ServerConfig
// ManagerReport
ManagerReport *databus.Config
// pprof
Pprof *Pprof
//Bfs
Bfs *Bfs
Prometheus *Prometheus
Apps *Apps
Cron *Cron
BroadCast *BroadCast
Gitlab *Gitlab
WeChat *WeChat
//Alarm
Alarm *Alarm
// Redis
// Redis *redis.Config
Redis *Redis
}
// Alarm .
type Alarm struct {
DatabusURL string
DatabusKey string
}
// WeChat .
type WeChat struct {
Users []string
ChatID string
}
// BroadCast .
type BroadCast struct {
TenCent []string
KingSoft []string
}
// Cron .
type Cron struct {
Crontab string
CrontabRepo string
}
// Prometheus .
type Prometheus struct {
URL string
Key string
Secret string
}
// Apps .
type Apps struct {
Name []string
Max int64
}
//UTBaseLine .
type UTBaseLine struct {
Coverage int
Passrate int
}
// Bfs bfs config
type Bfs struct {
Addr string
Bucket string
Key string
Secret string
MaxFileSize int
}
// Pprof dir path
type Pprof struct {
Dir string
GoPath string
}
// Databus config
type Databus struct {
Partitions int32
Factor int16
}
// Tree PlatformID
type Tree struct {
PlatformID string
MsmPlatformID string
}
// Host hosts
type Host struct {
APICo string
SVENCo string
MANAGERCo string
DapperCo string
}
//Canal canal
type Canal struct {
CANALSVENCo string
BUILD string
Reviewer []string
}
// Discovery discovery
type Discovery struct {
API []string
}
// Kafka kafka config
type Kafka struct {
Brokers []string
}
// Gitlab gitlab config
type Gitlab struct {
API string // gitlab api host
Token string // saga 账户 access token
}
// Redis .
type Redis struct {
*redis.Config
ExpireTime xtime.Duration
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init int config
func Init() error {
if confPath != "" {
return local()
}
return remote()
}

View File

@@ -0,0 +1,86 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"canal_test.go",
"dao_test.go",
"ecode_test.go",
"need_test.go",
"pprof_test.go",
"upload_test.go",
"ut_app_test.go",
"ut_rank_test.go",
"ut_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"canal.go",
"dao.go",
"ecode.go",
"monkey.go",
"need.go",
"pprof.go",
"upload.go",
"ut.go",
"ut_app.go",
"ut_rank.go",
],
importpath = "go-common/app/admin/main/apm/dao",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/ecode:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//app/admin/main/apm/model/pprof:go_default_library",
"//app/admin/main/apm/model/ut:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf/env:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/apm/dao/mock:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,96 @@
package dao
import (
cml "go-common/app/admin/main/apm/model/canal"
"go-common/library/ecode"
"go-common/library/log"
)
//SetConfigID set canal_apply table conf_id
func (d *Dao) SetConfigID(id int64, addr string) (err error) {
ups := map[string]interface{}{
"conf_id": id,
}
if err = d.DBCanal.Model(&cml.Apply{}).Where("addr = ?", addr).Updates(ups).Error; err != nil {
log.Error(" SetConfigID error(%v)", err)
err = ecode.SetConfigIDErr
return
}
return
}
//CanalInfoCounts count master_info
func (d *Dao) CanalInfoCounts(v *cml.ConfigReq) (cnt int, err error) {
if err = d.DBCanal.Model(&cml.Canal{}).Where("addr=?", v.Addr).Count(&cnt).Error; err != nil {
log.Error("apmSvc.CanalInfoCounts count error(%v)", err)
err = ecode.RequestErr
return
}
return
}
//CanalInfoEdit update master_info
func (d *Dao) CanalInfoEdit(v *cml.ConfigReq) (err error) {
ups := map[string]interface{}{
"remark": v.Mark,
"cluster": v.Project,
"leader": v.Leader,
}
if err = d.DBCanal.Model(&cml.Canal{}).Where("addr=?", v.Addr).Updates(ups).Error; err != nil {
log.Error(" CanalInfoEdit update error(%v)", err)
err = ecode.CanalApplyUpdateErr
return
}
return
}
//CanalApplyCounts count canal_apply
func (d *Dao) CanalApplyCounts(v *cml.ConfigReq) (cnt int, err error) {
if err = d.DBCanal.Model(&cml.Apply{}).Where("addr=?", v.Addr).Count(&cnt).Error; err != nil {
log.Error("apmSvc.CanalApplyEdit count error(%v)", err)
err = ecode.RequestErr
return
}
return
}
//CanalApplyEdit update canal_apply
func (d *Dao) CanalApplyEdit(v *cml.ConfigReq, username string) (err error) {
ups := map[string]interface{}{
"remark": v.Mark,
"operator": username,
"state": 1,
"cluster": v.Project,
"leader": v.Leader,
}
if err = d.DBCanal.Model(&cml.Apply{}).Where("addr=?", v.Addr).Updates(ups).Error; err != nil {
log.Error(" CanalApplyEdit update error(%v)", err)
err = ecode.CanalApplyUpdateErr
return
}
return
}
//CanalApplyCreate insert into canal_apply
func (d *Dao) CanalApplyCreate(v *cml.ConfigReq, username string) (err error) {
var (
ap = &cml.Apply{
Addr: v.Addr,
Remark: v.Mark,
State: 1,
Operator: username,
Cluster: v.Project,
Leader: v.Leader,
}
)
if err = d.DBCanal.Create(ap).Error; err != nil {
log.Error("apSvc.CanalApplyCreate create error(%v)", err)
err = ecode.CanalApplyErr
return
}
return
}

View File

@@ -0,0 +1,246 @@
package dao
import (
"fmt"
"reflect"
"testing"
cml "go-common/app/admin/main/apm/model/canal"
"github.com/bouk/monkey"
"github.com/jinzhu/gorm"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSetConfigID(t *testing.T) {
convey.Convey("SetConfigID", t, func(ctx convey.C) {
var (
id = int64(0)
addr = "127.0.0.1:8000"
db = &gorm.DB{
Error: fmt.Errorf("test"),
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetConfigID(id, addr)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When DB update return err", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Updates", func(_ *gorm.DB, _ interface{}, _ ...bool) *gorm.DB {
return db
})
err := d.SetConfigID(id, addr)
ctx.Convey("Then err should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, 70014)
})
})
ctx.Reset(func() {
monkey.UnpatchAll()
})
})
}
func TestDaoCanalInfoCounts(t *testing.T) {
convey.Convey("CanalInfoCounts", t, func(ctx convey.C) {
var (
v = &cml.ConfigReq{
Addr: "127.0.0.1:3308",
User: "admin",
Password: "admin",
Project: "main.web-svr",
Leader: "fss",
Databases: "ada",
Mark: "test",
}
db = &gorm.DB{
Error: fmt.Errorf("test"),
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cnt, err := d.CanalInfoCounts(v)
ctx.Convey("Then err should be nil.cnt should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cnt, convey.ShouldNotBeNil)
})
})
ctx.Convey("When count error", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Count", func(_ *gorm.DB, _ interface{}) *gorm.DB {
return db
})
cnt, err := d.CanalInfoCounts(v)
ctx.Convey("Then err should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, -400)
ctx.So(cnt, convey.ShouldEqual, 0)
})
})
ctx.Reset(func() {
monkey.UnpatchAll()
})
})
}
func TestDaoCanalInfoEdit(t *testing.T) {
convey.Convey("CanalInfoEdit", t, func(ctx convey.C) {
var (
v = &cml.ConfigReq{
Addr: "127.0.0.1:3308",
User: "admin",
Password: "admin",
Project: "main.web-svr",
Leader: "fss",
Databases: "ada",
Mark: "test",
}
db = &gorm.DB{
Error: fmt.Errorf("test"),
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.CanalInfoEdit(v)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When edit return err", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Updates", func(_ *gorm.DB, _ interface{}, _ ...bool) *gorm.DB {
return db
})
err := d.CanalInfoEdit(v)
ctx.Convey("Then err should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, 70005)
})
})
ctx.Reset(func() {
monkey.UnpatchAll()
})
})
}
func TestDaoCanalApplyCounts(t *testing.T) {
convey.Convey("CanalApplyCounts", t, func(ctx convey.C) {
var (
v = &cml.ConfigReq{
Addr: "127.0.0.1:3308",
User: "admin",
Password: "admin",
Project: "main.web-svr",
Leader: "fss",
Databases: "ada",
Mark: "test",
}
db = &gorm.DB{
Error: fmt.Errorf("test"),
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cnt, err := d.CanalApplyCounts(v)
ctx.Convey("Then err should be nil.cnt should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cnt, convey.ShouldNotBeNil)
})
})
ctx.Convey("When count error", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Count", func(_ *gorm.DB, _ interface{}) *gorm.DB {
return db
})
cnt, err := d.CanalApplyCounts(v)
ctx.Convey("Then err should not be nil.cnt should be 0.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, -400)
ctx.So(cnt, convey.ShouldEqual, 0)
})
})
ctx.Reset(func() {
monkey.UnpatchAll()
})
})
}
func TestDaoCanalApplyEdit(t *testing.T) {
convey.Convey("CanalApplyEdit", t, func(ctx convey.C) {
var (
v = &cml.ConfigReq{
Addr: "127.0.0.1:3308",
User: "admin",
Password: "admin",
Databases: "test",
Mark: "test",
}
db = &gorm.DB{
Error: fmt.Errorf("test"),
}
username = "fengshanshan"
)
ctx.Convey("When project and leader is null", func(ctx convey.C) {
err := d.CanalApplyEdit(v, username)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When everything goes positive", func(ctx convey.C) {
v.Leader = "fengshanshan"
v.Project = "main.web-svr"
err := d.CanalApplyEdit(v, username)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When edit error", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Updates", func(_ *gorm.DB, _ interface{}, _ ...bool) *gorm.DB {
return db
})
err := d.CanalApplyEdit(v, username)
ctx.Convey("Then err should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, 70005)
})
})
ctx.Reset(func() {
monkey.UnpatchAll()
})
})
}
func TestDaoCanalApplyCreate(t *testing.T) {
convey.Convey("CanalApplyCreate", t, func(ctx convey.C) {
var (
v = &cml.ConfigReq{
Addr: "127.0.0.1:3309",
User: "admin",
Password: "admin",
Project: "main.web-svr",
Leader: "fss",
Databases: "ada",
Mark: "test",
}
db = &gorm.DB{
Error: fmt.Errorf("test"),
}
username = "fengshanshan"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Create", func(_ *gorm.DB, _ interface{}) *gorm.DB {
return &gorm.DB{
Error: nil,
}
})
err := d.CanalApplyCreate(v, username)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When creater error", func(ctx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.DBCanal), "Create", func(_ *gorm.DB, _ interface{}) *gorm.DB {
return db
})
err := d.CanalApplyCreate(v, username)
ctx.Convey("Then err should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, 70006)
})
})
ctx.Reset(func() {
monkey.UnpatchAll()
})
})
}

View File

@@ -0,0 +1,54 @@
package dao
import (
"go-common/app/admin/main/apm/conf"
"go-common/library/cache/redis"
"go-common/library/database/orm"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
// Dao dao.
type Dao struct {
c *conf.Config
DB *gorm.DB
DBDatabus *gorm.DB
DBCanal *gorm.DB
// client
client *bm.Client
Redis *redis.Pool
}
// New new a dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
DB: orm.NewMySQL(c.ORM),
DBDatabus: orm.NewMySQL(c.ORMDatabus),
DBCanal: orm.NewMySQL(c.ORMCanal),
client: bm.NewClient(c.HTTPClient),
Redis: redis.NewPool(c.Redis.Config),
}
d.initORM()
return
}
func (d *Dao) initORM() {
d.DB.LogMode(true)
d.DBDatabus.LogMode(true)
d.DBCanal.LogMode(true)
}
// Close close connection of db , mc.
func (d *Dao) Close() {
if d.DB != nil {
d.DB.Close()
}
if d.DBDatabus != nil {
d.DBDatabus.Close()
}
if d.DBCanal != nil {
d.DBCanal.Close()
}
}

View File

@@ -0,0 +1,44 @@
package dao
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/admin/main/apm/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.common-arch.apm-admin")
flag.Set("conf_token", "1b457a53f52b11e7ab3616a6c13439ad")
flag.Set("tree_id", "11133")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/apm-admin-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,42 @@
package dao
import (
"context"
"fmt"
"net/http"
"net/url"
"go-common/app/admin/main/apm/model/ecode"
"go-common/library/log"
)
// const (
// _codesLangsSQL = "select a.code,a.message,a.mtime,IFNULL(b.locale,''),IFNULL(b.msg,''),IFNULL(b.mtime,'') as bmtime from codes as a left join code_msg as b on a.id=b.code_id"
// )
// GetCodes ...
func (d *Dao) GetCodes(c context.Context, Interval1, Interval2 string) (data []*codes.Codes, err error) {
var (
req *http.Request
uri = "http://sven.bilibili.co/x/admin/apm/ecode/get/ecodes"
ret = codes.ResultCodes{}
params = url.Values{}
)
params.Set("interval1", Interval1)
params.Set("interval2", Interval2)
if req, err = d.client.NewRequest(http.MethodGet, uri, "", params); err != nil {
log.Error("http.NewRequest error(%v)", err)
return
}
if err = d.client.Do(c, req, &ret); err != nil {
log.Error("client Do error(%v)", err)
return
}
if ret.Code != 0 {
err = fmt.Errorf("%s params(%s) response return_code(%d)", uri, params.Encode(), ret.Code)
log.Error("error(%v)", err)
return
}
data = ret.Data
return
}

View File

@@ -0,0 +1,17 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetCodes(t *testing.T) {
convey.Convey("GetCodes", t, func() {
res, err := d.GetCodes(context.Background(), "0", "20000")
t.Logf("res:%+v", res)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["monkey_dao.go"],
importpath = "go-common/app/admin/main/apm/dao/mock",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/apm/dao:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/ecode:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//app/admin/main/apm/model/pprof:go_default_library",
"//app/admin/main/apm/model/ut:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,219 @@
package mock
import (
"context"
"go-common/app/admin/main/apm/dao"
cml "go-common/app/admin/main/apm/model/canal"
"go-common/app/admin/main/apm/model/need"
"go-common/app/admin/main/apm/model/ecode"
"go-common/app/admin/main/apm/model/pprof"
"go-common/app/admin/main/apm/model/ut"
"reflect"
"github.com/bouk/monkey"
)
// MockDaoSetConfigID .
func MockDaoSetConfigID(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SetConfigID", func(_ *dao.Dao, _ int64, _ string) error {
return err
})
}
// MockDaoCanalInfoCounts .
func MockDaoCanalInfoCounts(d *dao.Dao, cnt int, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalInfoCounts", func(_ *dao.Dao, _ *cml.ConfigReq) (int, error) {
return cnt, err
})
}
// MockDaoCanalInfoEdit .
func MockDaoCanalInfoEdit(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalInfoEdit", func(_ *dao.Dao, _ *cml.ConfigReq) error {
return err
})
}
// MockDaoCanalApplyCounts .
func MockDaoCanalApplyCounts(d *dao.Dao, cnt int, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalApplyCounts", func(_ *dao.Dao, _ *cml.ConfigReq) (int, error) {
return cnt, err
})
}
// MockDaoCanalApplyEdit .
func MockDaoCanalApplyEdit(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalApplyEdit", func(_ *dao.Dao, _ *cml.ConfigReq, _ string) error {
return err
})
}
// MockDaoCanalApplyCreate .
func MockDaoCanalApplyCreate(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalApplyCreate", func(_ *dao.Dao, _ *cml.ConfigReq, _ string) error {
return err
})
}
// MockDaoGetCodes .
func MockDaoGetCodes(d *dao.Dao, data []*codes.Codes, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetCodes", func(_ *dao.Dao, _ context.Context, _ string, _ string) ([]*codes.Codes, error) {
return data, err
})
}
// MockDaoNeedInfoAdd .
func MockDaoNeedInfoAdd(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoAdd", func(_ *dao.Dao, _ *need.NAddReq, _ string) error {
return err
})
}
// MockDaoNeedInfoList .
func MockDaoNeedInfoList(d *dao.Dao, res []*need.NInfo, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoList", func(_ *dao.Dao, _ *need.NListReq) ([]*need.NInfo, error) {
return res, err
})
}
// MockDaoNeedInfoCount .
func MockDaoNeedInfoCount(d *dao.Dao, count int64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoCount", func(_ *dao.Dao, _ *need.NListReq) (int64, error) {
return count, err
})
}
// MockDaoGetNeedInfo .
func MockDaoGetNeedInfo(d *dao.Dao, r *need.NInfo, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetNeedInfo", func(_ *dao.Dao, _ int64) (*need.NInfo, error) {
return r, err
})
}
// MockDaoNeedInfoEdit .
func MockDaoNeedInfoEdit(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoEdit", func(_ *dao.Dao, _ *need.NEditReq) error {
return err
})
}
// MockDaoNeedVerify .
func MockDaoNeedVerify(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedVerify", func(_ *dao.Dao, _ *need.NVerifyReq) error {
return err
})
}
// MockDaoLikeCountsStats .
func MockDaoLikeCountsStats(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "LikeCountsStats", func(_ *dao.Dao, _ *need.Likereq, _ int, _ int) error {
return err
})
}
// MockDaoGetVoteInfo .
func MockDaoGetVoteInfo(d *dao.Dao, u *need.UserLikes, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetVoteInfo", func(_ *dao.Dao, _ *need.Likereq, _ string) (*need.UserLikes, error) {
return u, err
})
}
// MockDaoUpdateVoteInfo .
func MockDaoUpdateVoteInfo(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "UpdateVoteInfo", func(_ *dao.Dao, _ *need.Likereq, _ string) error {
return err
})
}
// MockDaoAddVoteInfo .
func MockDaoAddVoteInfo(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "AddVoteInfo", func(_ *dao.Dao, _ *need.Likereq, _ string) error {
return err
})
}
// MockDaoVoteInfoList .
func MockDaoVoteInfoList(d *dao.Dao, res []*need.UserLikes, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "VoteInfoList", func(_ *dao.Dao, _ *need.Likereq) ([]*need.UserLikes, error) {
return res, err
})
}
// MockDaoVoteInfoCounts .
func MockDaoVoteInfoCounts(d *dao.Dao, count int64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "VoteInfoCounts", func(_ *dao.Dao, _ *need.Likereq) (int64, error) {
return count, err
})
}
// MockDaoInstances .
func MockDaoInstances(d *dao.Dao, ins *pprof.Ins, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "Instances", func(_ *dao.Dao, _ context.Context, _ string) (*pprof.Ins, error) {
return ins, err
})
}
// MockDaoGitLabFace .
func MockDaoGitLabFace(d *dao.Dao, avatarURL string, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GitLabFace", func(_ *dao.Dao, _ context.Context, _ string) (string, error) {
return avatarURL, err
})
}
// MockDaoUploadProxy .
func MockDaoUploadProxy(d *dao.Dao, url string, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "UploadProxy", func(_ *dao.Dao, _ context.Context, _ string, _ int64, _ []byte) (string, error) {
return url, err
})
}
// MockDaoParseUTFiles .
func MockDaoParseUTFiles(d *dao.Dao, pkgs []*ut.PkgAnls, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "ParseUTFiles", func(_ *dao.Dao, _ context.Context, _ string) ([]*ut.PkgAnls, error) {
return pkgs, err
})
}
// MockDaoSendWechatToUsers .
func MockDaoSendWechatToUsers(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SendWechatToUsers", func(_ *dao.Dao, _ context.Context, _ []string, _ string) error {
return err
})
}
// MockDaoSendWechatToGroup .
func MockDaoSendWechatToGroup(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SendWechatToGroup", func(_ *dao.Dao, _ context.Context, _ string, _ string) error {
return err
})
}
// MockDaoGitLabCommits .
func MockDaoGitLabCommits(d *dao.Dao, commit *ut.GitlabCommit, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GitLabCommits", func(_ *dao.Dao, _ context.Context, _ string) (*ut.GitlabCommit, error) {
return commit, err
})
}
// MockDaoGetCoverage .
func MockDaoGetCoverage(d *dao.Dao, cov float64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetCoverage", func(_ *dao.Dao, _ context.Context, _ string, _ string) (float64, error) {
return cov, err
})
}
// MockDaoSetAppCovCache .
func MockDaoSetAppCovCache(d *dao.Dao, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SetAppCovCache", func(_ *dao.Dao, _ context.Context) error {
return err
})
}
// MockDaoGetAppCovCache .
func MockDaoGetAppCovCache(d *dao.Dao, coverage float64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetAppCovCache", func(_ *dao.Dao, _ context.Context, _ string) (float64, error) {
return coverage, err
})
}

View File

@@ -0,0 +1,202 @@
package dao
import (
"context"
cml "go-common/app/admin/main/apm/model/canal"
"go-common/app/admin/main/apm/model/ecode"
"go-common/app/admin/main/apm/model/need"
"go-common/app/admin/main/apm/model/pprof"
"go-common/app/admin/main/apm/model/ut"
"reflect"
"github.com/bouk/monkey"
)
//MockSetConfigID is
func (d *Dao) MockSetConfigID(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SetConfigID", func(_ *Dao, _ int64, _ string) error {
return err
})
}
//MockCanalInfoCounts is
func (d *Dao) MockCanalInfoCounts(cnt int, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalInfoCounts", func(_ *Dao, _ *cml.ConfigReq) (int, error) {
return cnt, err
})
}
//MockCanalInfoEdit is
func (d *Dao) MockCanalInfoEdit(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalInfoEdit", func(_ *Dao, _ *cml.ConfigReq) error {
return err
})
}
//MockCanalApplyCounts is
func (d *Dao) MockCanalApplyCounts(cnt int, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalApplyCounts", func(_ *Dao, _ *cml.ConfigReq) (int, error) {
return cnt, err
})
}
//MockCanalApplyEdit is
func (d *Dao) MockCanalApplyEdit(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalApplyEdit", func(_ *Dao, _ *cml.ConfigReq, _ string) error {
return err
})
}
//MockCanalApplyCreate is
func (d *Dao) MockCanalApplyCreate(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "CanalApplyCreate", func(_ *Dao, _ *cml.ConfigReq, _ string) error {
return err
})
}
//MockGetCodes is
func (d *Dao) MockGetCodes(data []*codes.Codes, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetCodes", func(_ *Dao, _ context.Context, _ string, _ string) ([]*codes.Codes, error) {
return data, err
})
}
//MockNeedInfoAdd is
func (d *Dao) MockNeedInfoAdd(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoAdd", func(_ *Dao, _ *need.NAddReq, _ string) error {
return err
})
}
//MockNeedInfoList is
func (d *Dao) MockNeedInfoList(res []*need.NInfo, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoList", func(_ *Dao, _ *need.NListReq) ([]*need.NInfo, error) {
return res, err
})
}
//MockNeedInfoCount is
func (d *Dao) MockNeedInfoCount(count int64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoCount", func(_ *Dao, _ *need.NListReq) (int64, error) {
return count, err
})
}
//MockGetNeedInfo is
func (d *Dao) MockGetNeedInfo(r []*need.NInfo, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetNeedInfo", func(_ *Dao, _ int64) ([]*need.NInfo, error) {
return r, err
})
}
//MockNeedInfoEdit is
func (d *Dao) MockNeedInfoEdit(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedInfoEdit", func(_ *Dao, _ *need.NEditReq) error {
return err
})
}
//MockNeedVerify is
func (d *Dao) MockNeedVerify(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "NeedVerify", func(_ *Dao, _ *need.NVerifyReq) error {
return err
})
}
//MockLikeCountsStats is
func (d *Dao) MockLikeCountsStats(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "LikeCountsStats", func(_ *Dao, _ *need.Likereq, _ int, _ int) error {
return err
})
}
//MockGetVoteInfo is
func (d *Dao) MockGetVoteInfo(u []*need.UserLikes, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetVoteInfo", func(_ *Dao, _ *need.Likereq, _ string) ([]*need.UserLikes, error) {
return u, err
})
}
//MockUpdateVoteInfo is
func (d *Dao) MockUpdateVoteInfo(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "UpdateVoteInfo", func(_ *Dao, _ *need.Likereq, _ string) error {
return err
})
}
//MockAddVoteInfo is
func (d *Dao) MockAddVoteInfo(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "AddVoteInfo", func(_ *Dao, _ *need.Likereq, _ string) error {
return err
})
}
//MockVoteInfoList is
func (d *Dao) MockVoteInfoList(res []*need.UserLikes, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "VoteInfoList", func(_ *Dao, _ *need.Likereq) ([]*need.UserLikes, error) {
return res, err
})
}
//MockVoteInfoCounts is
func (d *Dao) MockVoteInfoCounts(count int64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "VoteInfoCounts", func(_ *Dao, _ *need.Likereq) (int64, error) {
return count, err
})
}
//MockInstances is
func (d *Dao) MockInstances(ins *pprof.Ins, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "Instances", func(_ *Dao, _ context.Context, _ string) (*pprof.Ins, error) {
return ins, err
})
}
//MockGitLabFace is
func (d *Dao) MockGitLabFace(avatarURL string, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GitLabFace", func(_ *Dao, _ context.Context, _ string) (string, error) {
return avatarURL, err
})
}
//MockUploadProxy is
func (d *Dao) MockUploadProxy(url string, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "UploadProxy", func(_ *Dao, _ context.Context, _ string, _ int64, _ []byte) (string, error) {
return url, err
})
}
//MockParseUTFiles is
func (d *Dao) MockParseUTFiles(pkgs []*ut.PkgAnls, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "ParseUTFiles", func(_ *Dao, _ context.Context, _ string) ([]*ut.PkgAnls, error) {
return pkgs, err
})
}
//MockSendWechatToUsers is
func (d *Dao) MockSendWechatToUsers(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SendWechatToUsers", func(_ *Dao, _ context.Context, _ []string, _ string) error {
return err
})
}
//MockSendWechatToGroup is
func (d *Dao) MockSendWechatToGroup(err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "SendWechatToGroup", func(_ *Dao, _ context.Context, _ string, _ string) error {
return err
})
}
//MockGitLabCommits is
func (d *Dao) MockGitLabCommits(commit *ut.GitlabCommit, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GitLabCommits", func(_ *Dao, _ context.Context, _ string) (*ut.GitlabCommit, error) {
return commit, err
})
}
//MockGetCoverage is
func (d *Dao) MockGetCoverage(cov float64, err error) (guard *monkey.PatchGuard) {
return monkey.PatchInstanceMethod(reflect.TypeOf(d), "GetCoverage", func(_ *Dao, _ context.Context, _ string, _ string) (float64, error) {
return cov, err
})
}

View File

@@ -0,0 +1,181 @@
package dao
import (
"fmt"
"go-common/app/admin/main/apm/model/need"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_tableNeed = "needs"
_tableLike = "user_likes"
_addCountsSQL = "UPDATE needs SET like_counts=like_counts+?,dislike_counts=dislike_counts+? WHERE id=?"
)
//NeedInfoAdd add need info
func (d *Dao) NeedInfoAdd(r *need.NAddReq, username string) (err error) {
ni := &need.NInfo{
Title: r.Title,
Content: r.Content,
Reporter: username,
Status: 1,
}
if err = d.DB.Create(&ni).Error; err != nil {
err = errors.WithStack(err)
return
}
return
}
//NeedInfoList all need info
func (d *Dao) NeedInfoList(arg *need.NListReq) (res []*need.NInfo, err error) {
where := d.needInfoCondition(arg)
if err = d.DB.Table(_tableNeed).Where(where).Order("id DESC").Offset((arg.Pn - 1) * arg.Ps).Limit(arg.Ps).Find(&res).Error; err != nil {
err = errors.WithStack(err)
log.Error("NeedInfoList:%s", err)
return
}
return
}
//NeedInfoCount need info count
func (d *Dao) NeedInfoCount(arg *need.NListReq) (count int64, err error) {
where := d.needInfoCondition(arg)
if err = d.DB.Table(_tableNeed).Where(where).Count(&count).Error; err != nil {
log.Error("NeedInfoCount:%s", err)
return
}
return
}
//needInfoCondition is
func (d *Dao) needInfoCondition(arg *need.NListReq) (where string) {
where = "status !=5"
if arg.Status > 0 {
where += fmt.Sprintf(" and `status`='%d'", arg.Status)
}
if arg.Reporter != "" {
where += fmt.Sprintf(" and `reporter`='%s'", arg.Reporter)
}
return where
}
// GetNeedInfo is
func (d *Dao) GetNeedInfo(id int64) (r *need.NInfo, err error) {
r = &need.NInfo{}
if err = d.DB.Table(_tableNeed).Where("id=?", id).Find(r).Error; err != nil {
log.Error("GetNeedInfo:%s", err)
return
}
return
}
//NeedInfoEdit is
func (d *Dao) NeedInfoEdit(arg *need.NEditReq) (err error) {
if err = d.DB.Table(_tableNeed).Where("id=?", arg.ID).Updates(map[string]interface{}{"content": arg.Content, "title": arg.Title}).Error; err != nil {
log.Error("NeedInfoEdit:%s", err)
return
}
return
}
//NeedVerify is
func (d *Dao) NeedVerify(r *need.NVerifyReq) (err error) {
tx := d.DB.Begin()
if err = d.DB.Table(_tableNeed).Where("id=?", r.ID).Update("status", r.Status).Error; err != nil {
log.Error("NeedVerify:%s", err)
tx.Rollback()
return
}
tx.Commit()
return
}
//LikeCountsStats thumbsup counts
func (d *Dao) LikeCountsStats(r *need.Likereq, like, dislike int) (err error) {
tx := d.DB.Begin()
if err = d.DB.Exec(_addCountsSQL, like, dislike, r.ReqID).Error; err != nil {
err = errors.WithStack(err)
log.Error("LikeCountsStats:%s", err)
tx.Rollback()
return
}
tx.Commit()
return
}
//GetVoteInfo is
func (d *Dao) GetVoteInfo(r *need.Likereq, username string) (u *need.UserLikes, err error) {
u = &need.UserLikes{}
if err = d.DB.Table(_tableLike).Where("req_id=? and `user`=?", r.ReqID, username).Find(u).Error; err != nil {
err = errors.WithStack(err)
return
}
return
}
//UpdateVoteInfo is
func (d *Dao) UpdateVoteInfo(r *need.Likereq, username string) (err error) {
if err = d.DB.Table(_tableLike).Where("req_id=? and `user`=?", r.ReqID, username).Update("like_type", r.LikeType).Error; err != nil {
err = errors.WithStack(err)
log.Error("UpdateVoteInfo:%s", err)
return
}
return
}
//AddVoteInfo is
func (d *Dao) AddVoteInfo(r *need.Likereq, username string) (err error) {
ul := &need.UserLikes{
ReqID: r.ReqID,
User: username,
LikeType: r.LikeType,
}
if err = d.DB.Create(&ul).Error; err != nil {
err = errors.WithStack(err)
return
}
return
}
//voteInfoCondition is
func (d *Dao) voteInfoCondition(arg *need.Likereq) (where string) {
where = " like_type != 0 "
if arg.ReqID > 0 {
where += fmt.Sprintf(" and `req_id`='%d'", arg.ReqID)
}
if arg.LikeType > 0 {
where += fmt.Sprintf(" and `like_type`='%d'", arg.LikeType)
}
return where
}
//VoteInfoList is vote info
func (d *Dao) VoteInfoList(arg *need.Likereq) (res []*need.UserLikes, err error) {
where := d.voteInfoCondition(arg)
if err = d.DB.Table(_tableLike).Where(where).Find(&res).Error; err != nil {
err = errors.WithStack(err)
log.Error("VoteInfoList:%s", err)
return
}
return
}
//VoteInfoCounts vote info count
func (d *Dao) VoteInfoCounts(arg *need.Likereq) (count int64, err error) {
where := d.voteInfoCondition(arg)
if err = d.DB.Table(_tableLike).Where(where).Count(&count).Error; err != nil {
log.Error("VoteInfoCount:%s", err)
return
}
return
}

View File

@@ -0,0 +1,160 @@
package dao
import (
"reflect"
"testing"
"go-common/app/admin/main/apm/model/need"
"github.com/bouk/monkey"
"github.com/jinzhu/gorm"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoNeedInfoAdd(t *testing.T) {
convey.Convey("NeedInfoAdd", t, func() {
arg := &need.NAddReq{
Title: "wwe",
Content: "sds",
}
err := d.NeedInfoAdd(arg, "fengshanshan")
convey.So(err, convey.ShouldBeNil)
})
}
func TestDaoNeedInfoList(t *testing.T) {
convey.Convey("NeedInfoList", t, func() {
arg := &need.NListReq{
Status: 1,
Ps: 10,
Pn: 1,
}
res, err := d.NeedInfoList(arg)
t.Logf("res:%+v", res)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}
func TestDaoNeedInfoCount(t *testing.T) {
convey.Convey("NeedInfoCount", t, func() {
arg := &need.NListReq{
Status: 1,
}
count, err := d.NeedInfoCount(arg)
t.Logf("count:%+v", count)
convey.So(err, convey.ShouldBeNil)
convey.So(count, convey.ShouldNotBeNil)
})
}
func TestDaoneedInfoCondition(t *testing.T) {
convey.Convey("needInfoCondition", t, func() {
arg := &need.NListReq{}
p1 := d.needInfoCondition(arg)
t.Logf("condition:%+v", p1)
convey.So(p1, convey.ShouldNotBeNil)
})
}
func TestDaoGetNeedInfo(t *testing.T) {
convey.Convey("GetNeedInfo", t, func() {
r, err := d.GetNeedInfo(97)
t.Logf("GetNeedInfo:%+v", r)
convey.So(err, convey.ShouldBeNil)
convey.So(r, convey.ShouldNotBeNil)
})
}
func TestDaoNeedInfoEdit(t *testing.T) {
convey.Convey("NeedInfoEdit", t, func() {
arg := &need.NEditReq{
Content: "dsada",
Title: "fsd",
ID: 28,
}
err := d.NeedInfoEdit(arg)
convey.So(err, convey.ShouldBeNil)
})
}
func TestDaoNeedVerify(t *testing.T) {
convey.Convey("NeedVerify", t, func() {
v := &need.NVerifyReq{
ID: 28,
Status: 2,
}
err := d.NeedVerify(v)
convey.So(err, convey.ShouldBeNil)
})
}
func TestDaoLikeCountsAdd(t *testing.T) {
convey.Convey("LikeCountsAdd", t, func() {
v := &need.Likereq{
ReqID: 148,
LikeType: 1,
}
err := d.LikeCountsStats(v, 1, 0)
convey.So(err, convey.ShouldBeNil)
})
}
func TestDaoGetVoteInfo(t *testing.T) {
convey.Convey("GetVoteInfo", t, func() {
var (
db = &gorm.DB{
Error: nil,
}
v = &need.Likereq{
ReqID: 148,
LikeType: 1,
}
)
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.DB), "Find", func(_ *gorm.DB, _ interface{}, _ ...interface{}) *gorm.DB {
return db
})
defer guard.Unpatch()
res, err := d.GetVoteInfo(v, "fengshanshan")
t.Logf("res:%+v", res)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}
func TestDaoUpdateVoteInfo(t *testing.T) {
convey.Convey("UpdateVoteInfo", t, func() {
v := &need.Likereq{
ReqID: 30,
LikeType: 2,
}
err := d.UpdateVoteInfo(v, "fengshanshan")
convey.So(err, convey.ShouldBeNil)
})
}
func TestDaoVoteInfoList(t *testing.T) {
convey.Convey("VoteInfoList", t, func() {
arg := &need.Likereq{
ReqID: 11,
LikeType: 2,
}
res, err := d.VoteInfoList(arg)
t.Logf("res:%+v", res)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}
func TestDaoVoteInfoCounts(t *testing.T) {
convey.Convey("VoteInfoCounts", t, func() {
arg := &need.Likereq{
ReqID: 11,
LikeType: 1,
}
count, err := d.VoteInfoCounts(arg)
t.Logf("count:%+v", count)
convey.So(err, convey.ShouldBeNil)
convey.So(count, convey.ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,42 @@
package dao
import (
"context"
"fmt"
"net/http"
"net/url"
"go-common/app/admin/main/apm/model/pprof"
"go-common/library/conf/env"
"go-common/library/log"
)
// Instances get instances
func (d *Dao) Instances(c context.Context, appName string) (ins *pprof.Ins, err error) {
var (
req *http.Request
uri = d.c.Host.SVENCo + "/x/admin/apm/noauth/discovery/fetch"
ret = &pprof.Response{}
params = url.Values{}
)
params.Add("zone", env.Zone)
params.Add("env", env.DeployEnv)
params.Add("region", env.Region)
params.Add("appid", appName)
params.Add("status", "3")
if req, err = d.client.NewRequest(http.MethodGet, uri, "", params); err != nil {
log.Error("d.Instances http.NewRequest error(%v)", err)
return
}
if err = d.client.Do(c, req, ret); err != nil {
log.Error("d.Instances client Do error(%v)", err)
return
}
if ret.Code != 0 {
err = fmt.Errorf("%s params(%s) response return_code(%d)", uri, params.Encode(), ret.Code)
log.Error("d.Instance error(%v)", err)
return
}
ins = ret.Data
return
}

View File

@@ -0,0 +1,18 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoInstance(t *testing.T) {
convey.Convey("Instance", t, func() {
var appName = "main.app-svr.app-view"
ins, err := d.Instances(context.Background(), appName)
convey.So(err, convey.ShouldBeNil)
convey.So(ins, convey.ShouldNotEqual, nil)
})
}

View File

@@ -0,0 +1,66 @@
package dao
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"net/http"
"strconv"
)
func authorize(key, secret, method, bucket string, expire int64) (authorization string) {
var (
content string
hash2 hash.Hash
signature string
template = "%s\n%s\n\n%d\n"
)
content = fmt.Sprintf(template, method, bucket, expire)
hash2 = hmac.New(sha1.New, []byte(secret))
hash2.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(hash2.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}
// UploadProxy upload file to bfs with no filename.
func (d *Dao) UploadProxy(c context.Context, fileType string, expire int64, body []byte) (url string, err error) {
var (
req *http.Request
resp *http.Response
header http.Header
code string
bfs = d.c.Bfs
uploadURL = "/%s"
)
url = fmt.Sprintf(bfs.Addr+uploadURL, bfs.Bucket)
if req, err = http.NewRequest(http.MethodPut, url, bytes.NewReader(body)); err != nil {
err = fmt.Errorf("dao.UploadProxy NewRequest error(%v)", err)
return
}
authorization := authorize(bfs.Key, bfs.Secret, http.MethodPut, bfs.Bucket, expire)
req.Header.Set("Host", bfs.Addr)
req.Header.Add("Date", fmt.Sprint(expire))
req.Header.Add("Authorization", authorization)
req.Header.Add("Content-Type", fileType)
if resp, err = http.DefaultClient.Do(req); err != nil {
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("dao.UploadProxy error return_status(%d)", resp.StatusCode)
return
}
header = resp.Header
code = header.Get("Code")
if code != strconv.Itoa(http.StatusOK) {
err = fmt.Errorf("dao.UploadProxy Upload url(%s) return_code(%s)", url, code)
return
}
url = header.Get("Location")
return
}

View File

@@ -0,0 +1,45 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoauthorize(t *testing.T) {
convey.Convey("authorize", t, func(ctx convey.C) {
var (
key = d.c.Bfs.Key
secret = d.c.Bfs.Secret
method = "PUT"
bucket = d.c.Bfs.Bucket
expire = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
authorization := authorize(key, secret, method, bucket, expire)
ctx.Convey("Then authorization should not be nil.", func(ctx convey.C) {
ctx.So(authorization, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUploadProxy(t *testing.T) {
convey.Convey("UploadProxy", t, func(ctx convey.C) {
var (
c = context.Background()
fileType = ""
expire = int64(1)
body = []byte("")
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
httpMock("PUT", d.c.Bfs.Addr+"/"+d.c.Bfs.Bucket).Reply(200).SetHeader("Code", "200")
url, err := d.UploadProxy(c, fileType, expire, body)
ctx.Convey("Then err should be nil.url should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(url, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,183 @@
package dao
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/ut"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
const (
_sagaWechatURL = "http://uat-saga-admin.bilibili.co/ep/admin/saga/v2/wechat"
_gitCommitsAPI = "http://git.bilibili.co/api/v4/projects/682/repository/commits"
)
// ParseUTFiles parse html to get specific file
func (d *Dao) ParseUTFiles(c context.Context, url string) (pkgs []*ut.PkgAnls, err error) {
var (
req *http.Request
html []byte
files []string
)
if req, err = http.NewRequest(http.MethodGet, url, nil); err != nil {
log.Error("apmSvc.ParseUTFiless error (%v)", err)
return
}
if html, err = d.client.Raw(c, req); err != nil {
log.Error("apmSvc.ParseUTFiles error (%v)", err)
return
}
reg := regexp.MustCompile(`<option(.*)</option>`)
files = reg.FindAllString(string(html), -1)
for _, file := range files {
cov, _ := strconv.ParseFloat(file[strings.Index(file, "(")+1:strings.Index(file, "%)")], 64)
pkg := &ut.PkgAnls{
PKG: file[strings.Index(file, "go-common") : strings.Index(file, ".go")+3],
Coverage: cov,
HTMLURL: url + "#" + file[strings.Index(file, `="`)+2:strings.Index(file, `">`)],
}
pkgs = append(pkgs, pkg)
}
return
}
// SendWechatToUsers send msg to multiple users by saga-admin api
func (d *Dao) SendWechatToUsers(c context.Context, users []string, msg string) (err error) {
var (
req *http.Request
b = &bytes.Buffer{}
url = _sagaWechatURL + "/message/send"
res struct {
Code int `json:"code"`
Message string `json:"message"`
}
body = &ut.WechatUsersMsg{
ToUser: users,
Content: msg,
}
)
if err = json.NewEncoder(b).Encode(body); err != nil {
log.Error("apmSvc.SendWechatToUsers Error(%v)", err)
return
}
if req, err = http.NewRequest(http.MethodPost, url, b); err != nil {
log.Error("apmSvc.SendWechatToUsers Error(%v)", err)
return
}
if err = d.client.Do(c, req, &res); err != nil {
log.Error("apmSvc.SendWechatToUsers Error(%v)", err)
return
}
if res.Code != 0 {
err = fmt.Errorf("Http response Code(%v)!=0", res.Code)
log.Error("apmSvc.SendWechatToUsers Error(%v)", err)
return
}
return
}
// SendWechatToGroup send msg to a group by saga-admin api
func (d *Dao) SendWechatToGroup(c context.Context, chatid, msg string) (err error) {
var (
num int
req *http.Request
b = &bytes.Buffer{}
url = _sagaWechatURL + "/appchat/send"
body = &ut.WechatGroupMsg{
ChatID: chatid,
MsgType: "text",
Safe: 0,
}
)
msgBlock := strings.Split(msg, "\n")
if len(msgBlock)%40 == 0 {
num = len(msgBlock)/40 - 1
} else {
num = len(msgBlock) / 40
}
for i := 0; i <= num; i++ {
var (
res struct {
Code int `json:"code"`
Message string `json:"message"`
}
)
start, end := 40*i, 40*(i+1)
if end > len(msgBlock) {
end = len(msgBlock)
}
body.Text = &ut.TextContent{
Content: strings.Join(msgBlock[start:end], "\n") + fmt.Sprintf("\n(%d/%d)", i+1, num+1),
}
if err = json.NewEncoder(b).Encode(body); err != nil {
log.Error("apmSvc.SendWechatToGroup Error(%v)", err)
return
}
if req, err = http.NewRequest(http.MethodPost, url, b); err != nil {
log.Error("apmSvc.SendWechatToGroup Error(%v)", err)
return
}
if err = d.client.Do(c, req, &res); err != nil {
log.Error("apmSvc.SendWechatToGroup Error(%v)", err)
return
}
if res.Code != 0 {
err = fmt.Errorf("Http response Code(%v)!=0", res.Code)
log.Error("apmSvc.SendWechatToGroup Error(%v)", err)
return
}
}
return
}
// GitLabCommits transfer gitlab uri,now support get method
func (d *Dao) GitLabCommits(c context.Context, commitID string) (commit *ut.GitlabCommit, err error) {
var req *http.Request
params := url.Values{}
params.Set("private_token", conf.Conf.Gitlab.Token)
if req, err = http.NewRequest(http.MethodGet, _gitCommitsAPI+"/"+commitID+"?"+params.Encode(), nil); err != nil {
log.Error("GitLabCommits http.NewRequest error(%v) params(%s)", err, params.Encode())
return
}
if err = d.client.Do(c, req, &commit); err != nil {
log.Error("GitLabCommits d.client.Do error(%v) params(%s)", err, params.Encode())
return
}
return
}
// GetCoverage get the none-file coverage by commitID and pkg (pkg cannot be fileName)
func (d *Dao) GetCoverage(c context.Context, commitID, pkg string) (cov float64, err error) {
var (
count = strings.Count(pkg, "/")
file = &ut.File{}
)
if len(pkg) == 0 {
err = fmt.Errorf("The pkg should not be empty")
return
}
if pkg[len(pkg)-1] != '/' {
count++
}
err = d.DB.Select(`commit_id,substring_index(name,"/",?) as pkg,round(sum(covered_statements)/sum(statements)*100,2) as coverage`, count).Group(fmt.Sprintf(`commit_id,substring_index(name,"/",%d)`, count)).Having("commit_id=? and pkg=?", commitID, pkg).First(file).Error
if err == gorm.ErrRecordNotFound {
cov, err = 0.00, nil
return
} else if err != nil {
log.Error("dao.GetCoverage commitID(%s) pkg(%s) error(%v)", commitID, pkg, err)
return
}
cov = file.Coverage
return
}

View File

@@ -0,0 +1,58 @@
package dao
import (
"context"
"go-common/app/admin/main/apm/model/ut"
"go-common/library/cache/redis"
"go-common/library/log"
"time"
)
// SetAppCovCache set apps and depts coverage into redis.
func (d *Dao) SetAppCovCache(c context.Context) (err error) {
var (
apps []*ut.App
deptApps []*ut.App
conn = d.Redis.Get(c)
expireTime = int64(time.Duration(d.c.Redis.ExpireTime) / time.Second)
)
defer conn.Close()
if err = d.DB.Find(&apps).Error; err != nil {
log.Error("d.AddAppCovCache DB.Find Error(%v)", err)
return
}
if err = d.DB.Raw(`select substring_index(substring_index(path,"/",4),"/",-1) as path,avg(coverage) as coverage,max(mtime) as mtime from ut_app where has_ut=1 group by substring_index(substring_index(path,"/",4),"/",-1)`).
Find(&deptApps).Error; err != nil {
log.Error("d.AddAppCovCache DB.Find Error(%v)", err)
return
}
apps = append(apps, deptApps...)
for _, app := range apps {
if err = conn.Send("SETEX", app.Path, expireTime, app.Coverage); err != nil {
log.Error("d.AddAppCovCache Redis.SETEX Error(%v)", err)
return
}
}
return
}
// GetAppCovCache get apps and depts coverage from redis.
func (d *Dao) GetAppCovCache(c context.Context, path string) (coverage float64, err error) {
var (
conn = d.Redis.Get(c)
exist bool
key = path
)
defer conn.Close()
if exist, err = redis.Bool(conn.Do("EXISTS", key)); err != nil {
log.Error("d.GetAppCov Error(%v)", err)
return
}
if exist {
if coverage, err = redis.Float64(conn.Do("GET", key)); err != nil {
log.Error("d.GetAppCov Error(%v)", err)
return
}
}
return
}

View File

@@ -0,0 +1,41 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSetAppCovCache(t *testing.T) {
convey.Convey("SetAppCovCache", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
err := d.SetAppCovCache(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
// coverage, _ := d.GetAppCovCache(c, "main")
// t.Logf("\nthe coverage is %.2f\n", coverage)
})
})
})
}
func TestDaoGetAppCovCache(t *testing.T) {
convey.Convey("GetAppCovCache", t, func(ctx convey.C) {
var (
c = context.Background()
path = "main"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
coverage, err := d.GetAppCovCache(c, path)
ctx.Convey("Then err should be nil.coverage should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(coverage, convey.ShouldNotBeNil)
t.Logf("\nthe coverage is %.2f\n", coverage)
})
})
})
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"context"
"net/http"
"net/url"
"strings"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/ut"
"go-common/library/log"
)
const (
_gitUsersAPI = "http://git.bilibili.co/api/v4/users"
)
// GitLabFace return face of gitlab.
func (d *Dao) GitLabFace(c context.Context, username string) (avatarURL string, err error) {
params := url.Values{}
params.Set("username", username)
params.Set("private_token", conf.Conf.Gitlab.Token)
var req *http.Request
if req, err = http.NewRequest(http.MethodGet, _gitUsersAPI, strings.NewReader(params.Encode())); err != nil {
log.Error("http.NewRequest(%s) error(%v)", username, err)
return
}
res := make([]*ut.Image, 0)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if err = d.client.Do(c, req, &res); err != nil {
log.Error("d.client.Do(%s) error(%v)", username, err)
return
}
for _, v := range res {
avatarURL = v.AvatarURL
}
return
}

View File

@@ -0,0 +1,17 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGitLabFace(t *testing.T) {
username := "chenjianrong"
convey.Convey("GitLabFace", t, func() {
res, err := d.GitLabFace(context.Background(), username)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,144 @@
package dao
import (
"context"
"net/http"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestDaoParseUTFiles(t *testing.T) {
convey.Convey("ParseUTFiles", t, func(ctx convey.C) {
var (
c = context.Background()
url = "http://uat-i0.hdslb.com/bfs/test/03af5d0707e4c6ec41a3eb797c8e9897f124515c.html"
)
gock.Off()
d.client.SetTransport(http.DefaultClient.Transport)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
pkgs, err := d.ParseUTFiles(c, url)
//t.Logf("the pkg[0] is PKG: %s, Coverage: %v, HTMLURL: %s", pkgs[0].PKG, pkgs[0].Coverage, pkgs[0].HTMLURL)
ctx.Convey("Then err should be nil.pkgs should not be nil.", func(ctx convey.C) {
ctx.So(pkgs, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGitCommitInfo(t *testing.T) {
convey.Convey("GitCommitInfo", t, func(ctx convey.C) {
var (
c = context.Background()
commitID = "ae1377033a11ca85a19bca365af32a5b0ebea31c"
)
gock.Off()
d.client.SetTransport(http.DefaultClient.Transport)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
commit, err := d.GitLabCommits(c, commitID)
ctx.Convey("Then err should be nil. gitcommit should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(commit, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSendWechatToUsers(t *testing.T) {
convey.Convey("SendWechatToUsers", t, func(ctx convey.C) {
var (
c = context.Background()
users = []string{"zhaobingqing"}
msg = "给你我的小心心❤"
)
d.client.SetTransport(gock.DefaultTransport)
ctx.Convey("When everything gose postive", func(ctx convey.C) {
httpMock("POST", _sagaWechatURL+"/message/send").Reply(200).JSON(`{"code":0,"message":"0"}`)
err := d.SendWechatToUsers(c, users, msg)
ctx.Convey("Then err should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When http status != 200", func(ctx convey.C) {
httpMock("POST", _sagaWechatURL+"/message/send").Reply(404)
err := d.SendWechatToUsers(c, users, msg)
ctx.Convey("Then err should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
ctx.Convey("When http response code != 0", func(ctx convey.C) {
httpMock("POST", _sagaWechatURL+"/message/send").Reply(200).JSON(`{"code":-401,"message":"0"}`)
err := d.SendWechatToUsers(c, users, msg)
ctx.Convey("Then err should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
ctx.Reset(func() {
gock.Off()
d.client.SetTransport(http.DefaultClient.Transport)
})
})
}
func TestDaoSendWechatToGroup(t *testing.T) {
convey.Convey("SendWechatToGroup", t, func(ctx convey.C) {
var (
msg = "信息测试~@002157"
c = context.Background()
)
d.client.SetTransport(gock.DefaultTransport)
ctx.Convey("When everything gose postive", func(ctx convey.C) {
httpMock("POST", _sagaWechatURL+"/appchat/send").Reply(200).JSON(`{"code":0,"message":"0"}`)
err := d.SendWechatToGroup(c, d.c.WeChat.ChatID, msg)
ctx.Convey("Then err should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When http status != 200", func(ctx convey.C) {
httpMock("POST", _sagaWechatURL+"/appchat/send").Reply(404)
err := d.SendWechatToGroup(c, d.c.WeChat.ChatID, msg)
ctx.Convey("Then err should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
ctx.Convey("When http response code != 0", func(ctx convey.C) {
httpMock("POST", _sagaWechatURL+"/appchat/send").Reply(200).JSON(`{"code":-401,"message":"0"}`)
err := d.SendWechatToGroup(c, d.c.WeChat.ChatID, msg)
ctx.Convey("Then err should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
ctx.Reset(func() {
gock.Off()
d.client.SetTransport(http.DefaultClient.Transport)
})
})
}
func TestDaoGetCoverage(t *testing.T) {
convey.Convey("GetCoverage", t, func(ctx convey.C) {
var (
c = context.Background()
commitID = "8d2f1b49661c7089e2b595eafff326033a138c23"
pkg = "go-common/app/admin/main/apm"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cov, err := d.GetCoverage(c, commitID, pkg)
ctx.Convey("Then err should be nil.cov should not be nil.", func(ctx convey.C) {
// t.Logf("the cov of %s is %.2f", pkg, cov)
ctx.So(cov, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("When the pkg is empty string", func(ctx convey.C) {
pkg = ""
_, err := d.GetCoverage(c, commitID, pkg)
ctx.Convey("Then err should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,93 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"canal.go",
"dapper.go",
"databus.go",
"discovery.go",
"ecode.go",
"http.go",
"monitor.go",
"need.go",
"open.go",
"platform.go",
"pprof.go",
"rank.go",
"upload.go",
"user.go",
"ut.go",
"ut_app.go",
"ut_dash.go",
],
importpath = "go-common/app/admin/main/apm/http",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/model/app:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/databus:go_default_library",
"//app/admin/main/apm/model/ecode:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//app/admin/main/apm/model/pprof:go_default_library",
"//app/admin/main/apm/model/user:go_default_library",
"//app/admin/main/apm/model/ut:go_default_library",
"//app/admin/main/apm/service:go_default_library",
"//app/tool/saga/model:go_default_library",
"//library/conf/env:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/binding:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"apply_test.go",
"canal_test.go",
"ecode_test.go",
"need_test.go",
"notify_test.go",
"process_test.go",
"upload_test.go",
"user_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/apm/conf:go_default_library",
"//app/admin/main/apm/model/canal:go_default_library",
"//app/admin/main/apm/model/need:go_default_library",
"//app/admin/main/apm/service:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,425 @@
package http
import (
"fmt"
"go-common/app/admin/main/apm/model/app"
"go-common/library/ecode"
"go-common/library/log"
"strconv"
"strings"
bm "go-common/library/net/http/blademaster"
)
func appList(c *bm.Context) {
var err error
v := new(struct {
AppID string `form:"app_id"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
if err = c.Bind(v); err != nil {
return
}
var (
aa []*app.App
count int
lk = "%" + v.AppID + "%"
)
if v.AppID != "" {
err = apmSvc.DB.Where("app_id LIKE ?", lk).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
}
if err != nil {
log.Error("apmSvc.AppList error(%v)", err)
c.JSON(nil, err)
return
}
if v.AppID != "" {
err = apmSvc.DB.Where("app_id LIKE ?", lk).Model(&app.App{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&app.App{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.AppList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: aa,
Total: count,
}
c.JSON(data, nil)
}
func appAdd(c *bm.Context) {
var err error
username := name(c)
v := new(struct {
AppTreeID int64 `form:"app_tree_id" validate:"required"`
AppID string `form:"app_id" validate:"required"`
Limit int64 `form:"limit"`
})
if err = c.Bind(v); err != nil {
return
}
if err = apmSvc.AppAdd(c, username, v.AppTreeID, v.AppID, v.Limit); err != nil {
log.Error("apmSvc.appAdd error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func appEdit(c *bm.Context) {
var err error
v := new(struct {
ID int `form:"id" validate:"required"`
Limit int `form:"limit" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
a := &app.App{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appEdit find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"limit": v.Limit,
}
if err = apmSvc.DB.Model(&app.App{}).Where("id = ?", v.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.appEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": ups,
"Old": a,
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 2, int64(v.ID), "apmSvc.appEdit", sqlLog)
c.JSON(nil, err)
}
func appDelete(c *bm.Context) {
v := new(struct {
ID int `form:"id" validate:"required"`
})
username := name(c)
var err error
if err = c.Bind(v); err != nil {
return
}
a := &app.App{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appDelete find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(a).Error; err != nil {
log.Error("apmSvc.appDelete delete(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 3, int64(v.ID), "apmSvc.appDelete", a)
c.JSON(nil, err)
}
func appAuthList(c *bm.Context) {
v := new(struct {
AppID string `form:"app_id"`
ServiceID string `form:"service_id"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
aa []*app.Auth
count int
)
if v.AppID != "" && v.ServiceID != "" {
err = apmSvc.DB.Where("app_id=? and service_id=?", v.AppID, v.ServiceID).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else if v.AppID != "" {
err = apmSvc.DB.Where("app_id=?", v.AppID).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else if v.ServiceID != "" {
err = apmSvc.DB.Where("service_id=?", v.ServiceID).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
}
if err != nil {
log.Error("apmSvc.appAuthList error(%v)", err)
c.JSON(nil, err)
return
}
if v.AppID != "" {
err = apmSvc.DB.Where("app_id=?", v.AppID).Model(&app.Auth{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&app.Auth{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.appAuthList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: aa,
Total: count,
}
c.JSON(data, nil)
}
func appAuthAdd(c *bm.Context) {
v := new(struct {
AppTreeID int64 `form:"app_tree_id" validate:"required"`
AppID string `form:"app_id" validate:"required"`
ServiceTreeID int64 `form:"service_tree_id" validate:"required"`
ServiceID string `form:"service_id" validate:"required"`
RPCMethod string `form:"rpc_method"`
HTTPMethod string `form:"http_method"`
Quota int64 `form:"quota"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
if v.ServiceTreeID == v.AppTreeID {
log.Error("apmSvc.appAuthAdd service_tree_id=app_tree_id error(%v)", v.ServiceTreeID)
c.JSON(nil, ecode.RequestErr)
return
}
cnt := 0
if err = apmSvc.DB.Model(&app.Auth{}).Where("service_tree_id=? and app_tree_id=?", v.ServiceTreeID, v.AppTreeID).Count(&cnt).Error; err != nil {
log.Error("apmSvc.appAuthAdd count error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
if cnt > 0 {
log.Error("apmSvc.appAuthAdd count (%v)", cnt)
c.JSON(nil, ecode.RequestErr)
return
}
a := &app.Auth{
AppTreeID: v.AppTreeID,
AppID: v.AppID,
ServiceTreeID: v.ServiceTreeID,
ServiceID: v.ServiceID,
RPCMethod: v.RPCMethod,
HTTPMethod: v.HTTPMethod,
Quota: v.Quota,
}
if err = apmSvc.DB.Create(a).Error; err != nil {
log.Error("apmSvc.appAuthAdd create error(%v)", err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 1, a.ID, "apmSvc.appAuthAdd", a)
c.JSON(nil, err)
}
func appAuthEdit(c *bm.Context) {
v := new(struct {
ID int `form:"id" validate:"required"`
RPCMethod string `form:"rpc_method"`
HTTPMethod string `form:"http_method"`
Quota int `form:"quota" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
a := &app.Auth{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appAuthEdit find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"rpc_method": v.RPCMethod,
"http_method": v.HTTPMethod,
"quota": v.Quota,
}
if err = apmSvc.DB.Model(&app.Auth{}).Where("id = ?", v.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.appAuthEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": ups,
"Old": a,
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 2, int64(v.ID), "apmSvc.appAuthEdit", sqlLog)
c.JSON(nil, err)
}
func appAuthDelete(c *bm.Context) {
v := new(struct {
ID int `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
a := &app.Auth{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(a).Error; err != nil {
log.Error("apmSvc.appAuthDelete find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(a).Error; err != nil {
log.Error("apmSvc.appAuthDelete delete(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 3, int64(v.ID), "apmSvc.appAuthDelete", a)
c.JSON(nil, err)
}
func appTree(c *bm.Context) {
v := new(struct {
Bu string `form:"bu"`
Team string `form:"team"`
Name string `form:"name"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
trees, err := apmSvc.Trees(c, username, c.Request.Header.Get("Cookie"))
if err != nil {
log.Error("apmSvc.appTree error(%v)", err)
c.JSON(nil, err)
return
}
var data []string
temp := make(map[string]string)
if v.Bu == "" && v.Team == "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
newName := nameArr[1]
if f := temp[newName]; f == "" {
data = append(data, newName)
temp[newName] = newName
}
}
} else if v.Bu != "" && v.Team != "" && v.Name != "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
if v.Bu == nameArr[1] && v.Team == nameArr[2] && v.Name == nameArr[3] {
data = append(data, strconv.Itoa(val.TreeID))
}
}
} else if v.Bu != "" && v.Team != "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
if v.Bu == nameArr[1] && v.Team == nameArr[2] {
newName := nameArr[1] + "." + nameArr[2] + "." + nameArr[3]
if f := temp[newName]; f == "" {
data = append(data, nameArr[3])
temp[newName] = newName
}
}
}
} else if v.Bu != "" {
for _, val := range trees {
nameArr := strings.Split(val.Path, ".")
if v.Bu == nameArr[1] {
newName := v.Bu + "." + nameArr[2]
if f := temp[newName]; f == "" {
data = append(data, nameArr[2])
temp[newName] = newName
}
}
}
}
c.JSON(data, nil)
}
func appCallerSearch(c *bm.Context) {
v := new(struct {
AppID string `form:"app_id"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
aa []*app.Auth
count int
lk = "%" + v.AppID + "%"
)
if v.AppID != "" {
err = apmSvc.DB.Where("app_id LIKE ?", lk).Group("app_tree_id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
} else {
err = apmSvc.DB.Group("app_tree_id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&aa).Error
}
if err != nil {
log.Error("apmSvc.appCallerSearch error(%v)", err)
c.JSON(nil, err)
return
}
if v.AppID != "" {
err = apmSvc.DB.Select("count(distinct(app_tree_id))").Where("app_id LIKE ?", lk).Model(&app.Auth{}).Count(&count).Error
} else {
err = apmSvc.DB.Select("count(distinct(app_tree_id))").Model(&app.Auth{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.appCallerSearch count error(%v)", err)
c.JSON(nil, err)
return
}
type result struct {
AppTreeID int64 `gorm:"column:app_tree_id" json:"app_tree_id"`
AppID string `gorm:"column:app_id" json:"app_id"`
Services []*app.Auth
}
var results []*result
if count > 0 {
var in []int64
auth := []*app.Auth{}
for _, val := range aa {
in = append(in, val.AppTreeID)
fmt.Printf("apptreeid=%v", val.AppTreeID)
}
apmSvc.DB.Where("app_tree_id in (?)", in).Find(&auth)
for _, vv := range aa {
rs := new(result)
rs.AppTreeID = vv.AppTreeID
rs.AppID = vv.AppID
for _, vvv := range auth {
if vv.AppTreeID == vvv.AppTreeID {
rs.Services = append(rs.Services, vvv)
}
}
results = append(results, rs)
}
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: results,
Total: count,
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,134 @@
package http
import (
"context"
"flag"
"fmt"
"net/url"
"path/filepath"
"testing"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/service"
"go-common/library/log"
xhttp "go-common/library/net/http/blademaster"
. "github.com/smartystreets/goconvey/convey"
)
var (
_domain = "http://127.0.0.1:8000"
_contentType = "application/x-www-form-urlencoded"
_cookie = "username=fengshanshan; _AJSESSIONID=cf400491a236da90f27fb1b9bb9c4e2d; sven-apm=994ae2b6d290e584488443f9cc4733fbee7a88a4cd376135b1295f4cf81231de"
_realIP = "172.16.33.134"
_configuri = "%s/x/admin/apm/canal/apply/config"
_jsonstring = `[{ "schema":"123","table":[ {"name":"abc","primarykey":["order_id","new_id"],"omitfield":["new","old"]} , {"name":"def","primarykey":["order_id","new_id"],"omitfield":["new","old"] } ,{"name":"sfg","primarykey":["order_id","new_id"],"omitfield":["new","old"]} ],"databus": { "group": "LiveTime-LiveLive-P","addr": "172.16.33.158:6205"}},{ "schema":"456","table":[ {"name":"abc" ,"primarykey":["order_id","new_id"],"omitfield":["new","old"]} , {"name":"def" } ,{"name":"sfg"} ], "databus": {"group": "AccAnswer-MainManager-S","addr": "172.16.33.158:6205"}}]`
)
func init() {
dir, _ := filepath.Abs("../cmd/apm-admin-test.toml")
flag.Parse()
flag.Set("conf", dir)
conf.Init()
log.Init(conf.Conf.Log)
apmSvc = service.New(conf.Conf)
Init(conf.Conf, apmSvc)
}
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data string `json:"data"`
}
func requests(method, uri, realIP string, params url.Values, res interface{}) (err error) {
client := xhttp.NewClient(conf.Conf.HTTPClient)
req, err := client.NewRequest(method, uri, realIP, params)
if err != nil {
return
}
req.Header.Set("X-BACKEND-BILI-REAL-IP", _realIP)
req.Header.Set("Content-Type", _contentType)
req.Header.Set("Cookie", _cookie)
if err = client.Do(context.TODO(), req, &res); err != nil {
return
}
return
}
func TestApplyDetailToConfig(t *testing.T) {
Convey("TestApply register nonconfig and no canal_apply", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "admin")
params.Set("password", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, 70015)
})
Convey("TestApplyAddrIllegal", t, func() {
params := url.Values{}
params.Set("addr", "172.16.33.2553308")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "admin")
params.Set("passwd", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, 70002)
//So(res.Message, ShouldContainSubstring, "addr参数不合法")
})
Convey("TestApplyExist", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "admin")
params.Set("passwd", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, 0)
//So(res.Message, ShouldContainSubstring, "己提交申请")
})
Convey("TestApplyAddRequestParamError", t, func() {
params := url.Values{}
params.Set("leader", "fss")
params.Set("remark", "test")
params.Set("project", "main.web-svr")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
So(res.Code, ShouldEqual, -400)
})
}
func TestApplyExist(t *testing.T) {
Convey("TestApply register nonconfig and no canal_apply", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "demo")
params.Set("user", "a")
params.Set("password", "a")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_configuri, _domain), "", params, &res)
t.Logf("%+v", res)
So(res.Code, ShouldEqual, 70015)
})
}

View File

@@ -0,0 +1,291 @@
package http
import (
"context"
"strings"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/canal"
"go-common/app/admin/main/apm/model/user"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const (
_upsertMasterInfo = "INSERT INTO master_info (addr,remark,leader,cluster) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE remark=?,leader=?,cluster=?"
)
//canalList get canalinfo list
func canalList(c *bm.Context) {
var err error
v := new(canal.ListReq)
if err = c.Bind(v); err != nil {
return
}
data, _ := apmSvc.ProcessCanalList(c, v)
c.JSON(data, nil)
}
//canalList get canalinfo add
func canalAdd(c *bm.Context) {
v := new(canal.Canal)
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
err = apmSvc.ApplyAdd(c, v, username)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalList get canalinfo edit
func canalEdit(c *bm.Context) {
v := new(canal.EditReq)
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
if err = apmSvc.ApplyEdit(c, v, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalDelete 根据addr查询对应id进行软删除
func canalDelete(c *bm.Context) {
var err error
v := new(canal.ScanReq)
if err = c.Bind(v); err != nil {
return
}
username := name(c)
if err = apmSvc.ApplyDelete(c, v, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalScanByAddrFromConfig 根据Addr查询对应有效的配置
func canalScanByAddrFromConfig(c *bm.Context) {
var confData *canal.Results
cookie := c.Request.Header.Get("Cookie")
v := new(canal.ScanReq)
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
if confData, err = apmSvc.GetScanInfo(c, v, username, cookie); err != nil {
c.JSON(nil, err)
return
}
c.JSON(confData, nil)
}
func canalApplyList(c *bm.Context) {
v := new(canal.ListReq)
var err error
if err = c.Bind(v); err != nil {
return
}
data, err := apmSvc.ProcessApplyList(c, v)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
//canalApplyDetailToConfig is
func canalApplyDetailToConfig(c *bm.Context) {
var (
username string
err error
v = new(canal.ConfigReq)
cookie = c.Request.Header.Get("Cookie")
)
if u, err := c.Request.Cookie("username"); err == nil {
username = u.Value
} else {
username = "third"
}
if err = c.Bind(v); err != nil {
return
}
//judge legal params
f := strings.Contains(v.Addr, ":")
if !f {
log.Error("canalApplyAdd addr not standard error(%v)", err)
c.JSON(nil, ecode.CanalAddrFmtErr)
return
}
if v.User != "" && v.Password != "" {
if err = apmSvc.CheckMaster(c, v); err != nil {
c.JSON(nil, err)
return
}
}
if err = apmSvc.ProcessCanalInfo(c, v, username); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.ProcessConfigInfo(c, v, cookie, username); err != nil {
c.JSON(nil, err)
return
}
go apmSvc.SendWechatMessage(context.Background(), v.Addr, canal.TypeMap[canal.TypeApply], "", username, v.Mark, conf.Conf.Canal.Reviewer)
c.JSON(nil, err)
}
//canalApplyConfigEdit is
func canalApplyConfigEdit(c *bm.Context) {
cookie := c.Request.Header.Get("Cookie")
v := new(canal.ConfigReq)
if err := c.Bind(v); err != nil {
return
}
ap := &canal.Apply{}
err := apmSvc.DBCanal.Model(&canal.Apply{}).Select("`operator`").Where("addr=?", v.Addr).Find(ap).Error
if err != nil {
log.Error("no apply error", err)
err = ecode.CanalAddrNotFound
c.JSON(nil, err)
return
}
username := name(c)
err = apmSvc.Permit(c, username, user.CanalView)
err0 := apmSvc.Permit(c, username, user.CanalEdit)
if err != nil || (username != ap.Operator && err0 != nil) {
log.Error("permit(%v, %s,%s)", username, err)
c.JSON(nil, ecode.AccessDenied)
return
}
if v.User != "" && v.Password != "" {
if err = apmSvc.CheckMaster(c, v); err != nil {
c.JSON(nil, err)
return
}
}
if err0 != nil {
v = &canal.ConfigReq{
Addr: v.Addr,
MonitorPeriod: v.MonitorPeriod,
Databases: v.Databases,
Project: v.Project,
Leader: v.Leader,
Mark: v.Mark,
}
}
//judge legal params
f := strings.Contains(v.Addr, ":")
if !f {
log.Error("canalApplyAdd addr not standard error(%v)", err)
c.JSON(nil, ecode.CanalAddrFmtErr)
return
}
if err = apmSvc.ProcessCanalInfo(c, v, username); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.ProcessConfigInfo(c, v, cookie, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
//canalAddrAll get canal all addr info
func canalAddrAll(c *bm.Context) {
var (
list []string
items []*canal.Canal
)
err := apmSvc.DBCanal.Model(&canal.Canal{}).Where("is_delete= 0").Select("`addr`").Scan(&items).Error
if err != nil {
log.Error("canalAddrAll get addr error(%v)", err)
c.JSON(nil, err)
return
}
for _, v := range items {
list = append(list, v.Addr)
}
c.JSON(list, nil)
}
// canal 审核
func canalApplyApprovalProcess(c *bm.Context) {
var (
err error
)
cookie := c.Request.Header.Get("Cookie")
res := map[string]interface{}{}
v := new(struct {
ID int `form:"id" validate:"required"`
State int8 `form:"state" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
username := name(c)
apply := &canal.Apply{}
if err = apmSvc.DBCanal.Where("id = ?", v.ID).First(apply).Error; err != nil {
log.Error("canalApplyApprovalProcess id error(%v)", err)
c.JSON(nil, err)
return
}
if !(apply.State == 1 || apply.State == 2) {
log.Error("canalApplyApprovalProcess apply.state error(%v)", apply.State)
res["message"] = "只有申请中和打回才可审核"
c.JSONMap(res, ecode.RequestErr)
return
}
if !(v.State == 2 || v.State == 3 || v.State == 4) {
log.Error("canalApplyApprovalProcess v.state error(%v)", v.State)
res["message"] = "state值范围2,3,4"
c.JSONMap(res, ecode.RequestErr)
return
}
ups := map[string]interface{}{
"state": v.State,
}
if v.State == 3 && apply.State != 3 {
if err = apmSvc.UpdateProcessTag(c, apply.ConfID, cookie); err != nil {
log.Error("apmSvc.UpdateProcessTag error(%v)", apply.ID)
c.JSON(nil, err)
return
}
if err = apmSvc.DBCanal.Exec(_upsertMasterInfo, apply.Addr, apply.Remark, apply.Leader, apply.Cluster, apply.Remark, apply.Leader, apply.Cluster).Error; err != nil {
log.Error("canalProcess update master_info error(%v)", err)
c.JSONMap(nil, err)
return
}
}
// 更新apply
if err = apmSvc.DBCanal.Model(apply).Where("id = ?", apply.ID).Update(ups).Error; err != nil {
log.Error("canalApplyApprovalProcess update error(%v)", apply.ID)
res["message"] = "修改状态失败"
c.JSONMap(res, err)
return
}
go apmSvc.SendWechatMessage(context.Background(), apply.Addr, canal.TypeMap[canal.TypeReview], canal.TypeMap[v.State], username, "", []string{apply.Operator})
c.JSON(nil, err)
}

View File

@@ -0,0 +1,143 @@
package http
import (
"fmt"
"net/url"
"testing"
"go-common/app/admin/main/apm/model/canal"
. "github.com/smartystreets/goconvey/convey"
)
var (
_listuri = "%s/x/admin/apm/canal"
_scanurl = "%s/x/admin/apm/canal/scan"
_canalediturl = "%s/x/admin/apm/canal/apply/edit"
_addrallurl = "%s/x/admin/apm/canal/addrs"
_adduri = "%s/x/admin/apm/canal/add"
_deleteuri = "%s/x/admin/apm/canal/delete"
_edituri = "%s/x/admin/apm/canal/edit"
_applyurl = "%s/x/admin/apm/canal/apply"
)
func TestCanalList(t *testing.T) {
Convey("TestCanalList", t, func() {
params := url.Values{}
params.Set("project", "main.web-svr")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *canal.Paper `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_listuri, _domain), "", params, &res)
t.Logf("res:%+v", res.Data)
So(res.Code, ShouldEqual, 0)
})
}
func TestCanalAdd(t *testing.T) {
Convey("TestCanalAdd exists", t, func() {
params := url.Values{}
params.Set("addr", "172.16.33.866:3308")
params.Set("bin_name", "fss")
params.Set("bin_pos", "1")
params.Set("remark", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_adduri, _domain), "", params, &res)
t.Logf("res:%+v", res)
//So(res.Message, ShouldContainSubstring, "exist")
//So(res.Code, ShouldEqual, -400)
})
}
func TestCanalEdit(t *testing.T) {
Convey("TestCanalEdit", t, func() {
params := url.Values{}
params.Set("id", "8384")
params.Set("bin_name", "rtwew")
params.Set("bin_pos", "20")
params.Set("remark", "inesww")
params.Set("project", "main.web-svrq")
params.Set("leader", "dsa")
res := Response{}
_ = requests("POST", fmt.Sprintf(_edituri, _domain), "", params, &res)
t.Logf("res:%+v", res)
})
}
func TestCanalDelete(t *testing.T) {
Convey("TestCanalDelete", t, func() {
params := url.Values{}
params.Set("addr", "ewe")
res := Response{}
_ = requests("POST", fmt.Sprintf(_deleteuri, _domain), "", params, &res)
t.Logf("res:%+v", res)
})
}
func TestScanFromConfig(t *testing.T) {
Convey("TestScanFromConfig", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.34:8902")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *canal.Results `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_scanurl, _domain), "", params, &res)
t.Logf("res:%+v", res.Data.Document)
})
}
func TestApplyLists(t *testing.T) {
Convey("TestApplyList", t, func() {
params := url.Values{}
//params.Set("addr", "172.16.33.243:3308")
params.Set("project", "main.web-svr")
params.Set("status", "1")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *canal.Paper `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_applyurl, _domain), "", params, &res)
t.Logf("res:%v", res.Data)
})
}
func TestApplyConfigEdit(t *testing.T) {
Convey("TestApplyConfigEdit", t, func() {
params := url.Values{}
params.Set("addr", "10.20.30.37:8902")
params.Set("databases", _jsonstring)
params.Set("mark", "fss")
params.Set("user", "admin")
params.Set("password", "admin")
params.Set("project", "main.web-svr")
params.Set("leader", "fss")
res := Response{}
_ = requests("POST", fmt.Sprintf(_canalediturl, _domain), "", params, &res)
t.Logf("res:%v", res)
})
}
func TestCanalAddrAll(t *testing.T) {
Convey("TestCanalAddrAll", t, func() {
params := url.Values{}
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data []string `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_addrallurl, _domain), "", params, &res)
t.Logf("res:%v", res.Data)
})
}

View File

@@ -0,0 +1,9 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
func dapperProxy(c *bm.Context) {
apmSvc.DapperProxy(c.Writer, c.Request)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
package http
import (
"strings"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func discoveryProxy(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/discovery/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.DiscoveryProxy(c, req.Method, req.URL.Path[idx+len("/x/admin/apm/discovery/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func discoveryProxyNoAuth(c *bm.Context) {
req := c.Request
data, err := apmSvc.DiscoveryProxy(c, req.Method, "fetch", req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,492 @@
package http
import (
"encoding/json"
"go-common/app/admin/main/apm/model/ecode"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func ecodeList(c *bm.Context) {
v := new(struct {
Code string `form:"code"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
cs []*codes.Codes
count int
lk = "%" + v.Code + "%"
)
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
}
if err != nil {
log.Error("apmSvc.EcodeList error(%v)", err)
c.JSON(nil, err)
return
}
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Model(&codes.Codes{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&codes.Codes{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.EcodeList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: cs,
Total: count,
}
c.JSON(data, nil)
}
func ecodeAdd(c *bm.Context) {
v := new(struct {
Code int32 `form:"code" validate:"required"`
Message string `form:"message" validate:"required"`
HantMessage string `form:"hant_message"`
Level int8 `form:"level" default:"2"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
cnt := 0
if err = apmSvc.DB.Model(&codes.Codes{}).Where("code=?", v.Code).Count(&cnt).Error; err != nil {
log.Error("apmSvc.EcodeAdd count error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
username := name(c)
code := &codes.Codes{
Code: v.Code,
Message: v.Message,
HantMessage: v.HantMessage,
Level: v.Level,
Operator: username,
}
if err = apmSvc.DB.Create(&code).Error; err != nil {
log.Error("apmSvc.EcodeAdd create error(%v)", err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 1, code.ID, "apmSvc.EcodeAdd", code)
c.JSON(nil, err)
}
func ecodeEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Code int32 `form:"code" validate:"required"`
Message string `form:"message" validate:"required"`
HantMessage string `form:"hant_message"`
Level int8 `form:"level" default:"2"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
code := &codes.Codes{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(code).Error; err != nil {
log.Error("apmSvc.EcodeEdit find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
username := name(c)
ups := map[string]interface{}{
"code": v.Code,
"message": v.Message,
"operator": username,
"hant_message": v.HantMessage,
"level": v.Level,
}
if err = apmSvc.DB.Model(&codes.Codes{}).Where("id = ?", v.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.EcodeEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": ups,
"Old": code,
}
apmSvc.SendLog(*c, username, 0, 2, v.ID, "apmSvc.EcodeEdit", sqlLog)
c.JSON(nil, err)
}
func ecodeDelete(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
code := &codes.Codes{}
if err = apmSvc.DB.Where("id = ?", v.ID).Find(code).Error; err != nil {
log.Error("apmSvc.EcodeDelete find(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(code).Error; err != nil {
log.Error("apmSvc.EcodeDelete delete(%d) error(%v)", v.ID, err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 3, code.ID, "apmSvc.EcodeDelete", code)
c.JSON(nil, err)
}
func getEcodes(c *bm.Context) {
v := new(struct {
Interval1 int `form:"interval1" default:"0"`
Interval2 int `form:"interval2" default:"0"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
codes := []*codes.Codes{}
if err = apmSvc.DB.Where("code >= ? and code <= ?", v.Interval1, v.Interval2).Find(&codes).Error; err != nil {
log.Error("getEcodes error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(codes, nil)
}
func syncEcodes(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
username := name(c)
var Codes []*codes.Codes
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
var in []int32
for _, val := range Codes {
in = append(in, val.Code)
}
oldCodes := []*codes.Codes{}
if err = apmSvc.DB.Where("code in (?)", in).Find(&oldCodes).Error; err != nil {
log.Error("getEcodes error(%v)", err)
c.JSON(nil, err)
return
}
tmp := make(map[int32]struct{})
for _, val := range oldCodes {
tmp[val.Code] = struct{}{}
}
var code *codes.Codes
tx := apmSvc.DB.Begin()
for _, val := range Codes {
code = &codes.Codes{}
code.Code = val.Code
code.Message = val.Message
code.HantMessage = val.HantMessage
code.Level = val.Level
code.Operator = username
if _, ok := tmp[val.Code]; ok {
//update
if err = tx.Model(codes.Codes{}).Where("code = ?", val.Code).Updates(code).Error; err != nil {
tx.Rollback()
c.JSON(nil, err)
return
}
} else {
//create
if err = tx.Create(code).Error; err != nil {
tx.Rollback()
c.JSON(nil, err)
return
}
}
}
tx.Commit()
c.JSON(nil, err)
}
func getProdEcodes(c *bm.Context) {
v := new(struct {
Interval1 string `form:"interval1" default:"0"`
Interval2 string `form:"interval2" default:"0"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
Data, err := apmSvc.GetCodes(c, v.Interval1, v.Interval2)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(Data, nil)
}
func codeLangsList(c *bm.Context) {
v := new(struct {
Code string `form:"code"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
cs []*codes.Codes
count int
lk = "%" + v.Code + "%"
in []int64
ts []*codes.CodeMsg
res []*codes.NewCodes
)
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
} else {
err = apmSvc.DB.Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&cs).Error
}
if err != nil {
log.Error("apmSvc.EcodeList error(%v)", err)
c.JSON(nil, err)
return
}
for _, val := range cs {
in = append(in, val.ID)
}
err = apmSvc.DB.Where("code_id in(?)", in).Find(&ts).Error
if err != nil {
log.Error("apmSvc.EcodeList error(%v)", err)
c.JSON(nil, err)
return
}
for _, val := range cs {
list := make([]*codes.CodeMsg, 0)
for _, vv := range ts {
if vv.CodeID == val.ID {
list = append(list, vv)
}
}
res = append(res, &codes.NewCodes{Codes: val, List: list})
}
if v.Code != "" {
err = apmSvc.DB.Where("CAST(code AS CHAR) LIKE ? OR message LIKE ?", lk, lk).Model(&codes.Codes{}).Count(&count).Error
} else {
err = apmSvc.DB.Model(&codes.Codes{}).Count(&count).Error
}
if err != nil {
log.Error("apmSvc.EcodeList count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: res,
Total: count,
}
c.JSON(data, nil)
}
func ecodeLangsAdd(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var Codes []*codes.CodeMsg
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
username := name(c)
for _, val := range Codes {
if !(val.CodeID > 0 && len(val.Locale) > 0 && len(val.Msg) > 0) {
err = ecode.RequestErr
res["message"] = "数据有误"
c.JSONMap(res, err)
return
}
code := &codes.CodeMsg{
CodeID: val.CodeID,
Locale: val.Locale,
Msg: val.Msg,
Operator: username,
}
if err = apmSvc.DB.Create(&code).Error; err != nil {
log.Error("apmSvc.ecodeLangsAdd create error(%v)", err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 1, code.ID, "apmSvc.ecodeLangsAdd", code)
}
c.JSON(nil, err)
}
func ecodeLangsEdit(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var Codes []*codes.CodeMsg
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
username := name(c)
for _, val := range Codes {
code := &codes.CodeMsg{}
if err = apmSvc.DB.Where("id = ?", val.ID).First(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsEdit find(%d) error(%v)", val.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"operator": username,
"msg": val.Msg,
"locale": val.Locale,
}
if err = apmSvc.DB.Model(&codes.CodeMsg{}).Where("id = ?", val.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.ecodeLangsEdit updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": val.ID,
"Update": ups,
"Old": code,
}
apmSvc.SendLog(*c, username, 0, 2, val.ID, "apmSvc.ecodeLangsEdit", sqlLog)
}
c.JSON(nil, err)
}
func ecodeLangsDelete(c *bm.Context) {
v := new(struct {
CID int64 `form:"cid" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
code := &codes.CodeMsg{}
if err = apmSvc.DB.Where("id = ?", v.CID).First(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsDelete find(%d) error(%v)", v.CID, err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Delete(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsDelete delete(%d) error(%v)", v.CID, err)
c.JSON(nil, err)
return
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 3, code.ID, "apmSvc.ecodeLangsDelete", code)
c.JSON(nil, err)
}
func ecodeLangsSave(c *bm.Context) {
res := map[string]interface{}{}
v := new(struct {
Data string `form:"data" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var Codes []*codes.CodeMsg
err = json.Unmarshal([]byte(v.Data), &Codes)
if err != nil {
res["message"] = "解析失败"
c.JSONMap(res, err)
return
}
username := name(c)
for _, val := range Codes {
code := &codes.CodeMsg{}
if val.ID == 0 {
if !(val.CodeID > 0 && len(val.Locale) > 0 && len(val.Msg) > 0) {
err = ecode.RequestErr
res["message"] = "数据有误"
c.JSONMap(res, err)
return
}
code = &codes.CodeMsg{
CodeID: val.CodeID,
Locale: val.Locale,
Msg: val.Msg,
Operator: username,
}
if err = apmSvc.DB.Create(&code).Error; err != nil {
log.Error("apmSvc.ecodeLangsSvae create error(%v)", err)
c.JSON(nil, err)
return
}
apmSvc.SendLog(*c, username, 0, 1, code.ID, "apmSvc.ecodeLangsAdd", code)
} else {
if err = apmSvc.DB.Where("id = ?", val.ID).First(code).Error; err != nil {
log.Error("apmSvc.ecodeLangsSvae find(%d) error(%v)", val.ID, err)
c.JSON(nil, err)
return
}
ups := map[string]interface{}{
"operator": username,
"msg": val.Msg,
"locale": val.Locale,
}
if err = apmSvc.DB.Model(&codes.CodeMsg{}).Where("id = ?", val.ID).Updates(ups).Error; err != nil {
log.Error("apmSvc.ecodeLangsSave updates error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": val.ID,
"Update": ups,
"Old": code,
}
apmSvc.SendLog(*c, username, 0, 2, val.ID, "apmSvc.ecodeLangsSave", sqlLog)
}
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,17 @@
package http
//import (
// "testing"
//
// "flag"
//
// . "github.com/smartystreets/goconvey/convey"
//)
//
//func TestEcodeList(t *testing.T) {
// Convey("test ecode list", t, func() {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// c := request(nil)
// ecodeList(&c)
// })
//}

View File

@@ -0,0 +1,283 @@
package http
import (
"net/http"
"go-common/app/admin/main/apm/conf"
per "go-common/app/admin/main/apm/model/user"
"go-common/app/admin/main/apm/service"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
mpermit "go-common/library/net/http/blademaster/middleware/permit"
)
var (
apmSvc *service.Service
authSrv *mpermit.Permit
)
// Init init http sever instance.
func Init(c *conf.Config, s *service.Service) {
apmSvc = s
authSrv = mpermit.New(c.Auth)
engine := bm.DefaultServer(c.BM)
innerRouter(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
// innerRouter init inner router.
func innerRouter(e *bm.Engine) {
e.Ping(ping)
b := e.Group("x/admin/apm", authSrv.Verify())
{
code := b.Group("/ecode")
{
code.POST("/add", permit(per.EcodeEdit), ecodeAdd)
code.POST("/edit", permit(per.EcodeEdit), ecodeEdit)
code.POST("/delete", permit(per.EcodeEdit), ecodeDelete)
code.POST("/sync/ecodes", permit(per.EcodeEdit), syncEcodes)
code.POST("/langs/add", permit(per.EcodeEdit), ecodeLangsAdd)
code.POST("/langs/edit", permit(per.EcodeEdit), ecodeLangsEdit)
code.POST("/langs/delete", permit(per.EcodeEdit), ecodeLangsDelete)
code.POST("/langs/save", permit(per.EcodeEdit), ecodeLangsSave)
}
user := b.Group("/user")
{
user.GET("/auth", userAuth)
user.GET("/rule/states", userRuleStates)
user.POST("/apply", userApply)
user.POST("/apply/edit", permit(per.UserEdit), userApplyEdit)
user.GET("/users", userList)
user.GET("/info", permit(per.UserView), userInfo)
user.POST("/edit", permit(per.UserEdit), userEdit)
user.GET("/modules", permit(per.UserEdit), userModules)
user.GET("/rules", permit(per.UserEdit), userRules)
user.POST("/module/edit", permit(per.UserEdit), userModulesEdit)
user.POST("/rule/edit", permit(per.UserEdit), userRulesEdit)
user.GET("/applies", userApplies)
user.POST("/audit", userAudit)
// sync
user.GET("/tree/sync", userSyncTree)
user.GET("/tree/appids", userTreeAppids)
user.GET("/tree/discovery", userTreeDiscovery)
}
databus := b.Group("/databus")
{
// project
databus.GET("/projects", permit(per.DatabusKeyView), databusProjects)
// app
databus.GET("/apps", permit(per.DatabusKeyView), databusApps)
databus.POST("/app/add", permit(per.DatabusKeyEdit), databusAppAdd)
databus.POST("/app/edit", permit(per.DatabusKeyEdit), databusAppEdit)
// group
databus.GET("/groups", permit(per.DatabusGroupView), databusGroups)
databus.GET("/group/projects", permit(per.DatabusGroupView), databusGroupProjects)
databus.GET("/group/consumer/addrs", permit(per.DatabusGroupView), databusConsumerAddrs)
databus.POST("/group/sub/add", permit(per.DatabusGroupEdit), databusGroupSubAdd)
databus.POST("/group/pub/add", permit(per.DatabusGroupEdit), databusGroupPubAdd)
databus.POST("/group/delete", permit(per.DatabusGroupEdit), databusGroupDelete)
databus.POST("/group/rename", permit(per.DatabusGroupEdit), databusGroupRename)
databus.GET("/group/offset", permit(per.DatabusGroupView), databusGroupOffset)
databus.POST("/group/marked", permit(per.DatabusGroupEdit), databusGroupMarked)
databus.POST("/group/begin", permit(per.DatabusGroupEdit), databusGroupBegin)
databus.POST("/group/new/offset", permit(per.DatabusGroupEdit), databusGroupNewOffset)
databus.POST("/group/time", permit(per.DatabusGroupEdit), databusGroupTime)
// topic
databus.GET("/topics", permit(per.DatabusTopicView), databusTopics)
databus.GET("/topic/names", permit(per.DatabusGroupView), databusTopicNames)
databus.POST("/topic/add", permit(per.DatabusTopicEdit), databusTopicAdd)
databus.POST("/topic/edit", permit(per.DatabusTopicEdit), databusTopicEdit)
databus.GET("/topic/all", permit(per.DatabusGroupView), databusTopicAll)
// alarm
databus.POST("/alarm/edit", permit(per.DatabusGroupView), databusAlarmEdit)
databus.POST("/alarm/init", permit(per.DatabusGroupView), databusAlarmInit)
databus.POST("/alarm/all/edit", permit(per.DatabusGroupView), databusAlarmAllEdit)
// apply
databus.GET("/apply/list", permit(per.DatabusGroupView), databusApplyList)
databus.POST("/apply/pub/add", permit(per.DatabusGroupView), databusApplyPubAdd)
databus.POST("/apply/sub/add", permit(per.DatabusGroupView), databusApplySubAdd)
databus.POST("/apply/edit", permit(per.DatabusGroupView), databusApplyEdit)
databus.POST("/apply/approval/process", permit(per.DatabusGroupApply), databusApplyApprovalProcess)
// notify
databus.GET("/notify/apply/list", permit(per.DatabusGroupView), databusNotifyList)
databus.POST("/notify/edit", permit(per.DatabusNotifyEdit), databusNotifyEdit)
databus.POST("/notify/apply/add", permit(per.DatabusGroupView), databusNotifyApplyAdd)
// databus.POST("/notify/filter/add", databusNotifyFilterAdd)
// databus.POST("/notify/filter/edit", databusNotifyFilterEdit)
// message
databus.GET("/message/fetch", permit(per.DatabusGroupView), databusMsgFetch)
}
canal := b.Group("/canal")
{
canal.GET("", permit(per.CanalView), canalList)
canal.POST("/add", permit(per.CanalEdit), canalAdd)
canal.POST("/edit", permit(per.CanalEdit), canalEdit)
canal.POST("/delete", permit(per.CanalEdit), canalDelete)
canal.GET("/scan", permit(per.CanalView), canalScanByAddrFromConfig)
e.POST("x/admin/apm/canal/apply/config", canalApplyDetailToConfig)
canal.GET("/addrs", permit(per.CanalView), canalAddrAll)
canal.POST("/apply/edit", permit(per.CanalView), canalApplyConfigEdit)
canal.GET("/apply", permit(per.CanalView), canalApplyList)
canal.POST("/apply/approval/process", permit(per.CanalEdit), canalApplyApprovalProcess)
}
need := b.Group("/need")
{
need.GET("/list", needList)
need.POST("/add", needAdd)
need.POST("/edit", needEdit)
need.POST("/verify", permit(per.NeedVerify), needVerify)
need.POST("/thumbsup", needThumbsUp)
need.GET("/vote/list", permit(per.NeedVerify), needVoteList)
}
discovery := b.Group("/discovery")
{
discovery.GET("/", discoveryProxy)
}
app := b.Group("/app")
{
app.GET("/list", permit(per.AppView), appList)
app.POST("/add", permit(per.AppEdit), appAdd)
app.POST("/edit", permit(per.AppEdit), appEdit)
app.POST("/delete", permit(per.AppEdit), appDelete)
app.GET("/auth/list", permit(per.AppAuthView), appAuthList)
app.POST("/auth/add", permit(per.AppEdit), appAuthAdd)
app.POST("/auth/edit", permit(per.AppEdit), appAuthEdit)
app.POST("/auth/delete", permit(per.AppEdit), appAuthDelete)
app.GET("/caller/search", permit(per.AppEdit), appCallerSearch)
//tree
app.GET("/tree", permit(per.AppEdit), appTree)
}
platform := b.Group("/platform")
{
platform.GET("/search/get/", permit(per.PlatformSearchView), searchProxyGet)
platform.POST("/search/post/", permit(per.PlatformSearchView), searchProxyPost)
platform.GET("/reply/get/", permit(per.PlatformReplyView), replyProxyGet)
platform.POST("/reply/post/", permit(per.PlatformReplyView), replyProxyPost)
platform.GET("/tag/get/", permit(per.PlatformTagView), tagProxyGet)
platform.POST("/tag/post/", permit(per.PlatformTagView), tagProxyPost)
platform.GET("/bfs/get/", permit(per.BFSView), bfsProxyGet)
platform.POST("/bfs/post/", permit(per.BFSEdit), bfsProxyPost)
platform.GET("/reply/feed/get/", permit(per.PlatformReplyView), replyFeedProxyGet)
platform.POST("/reply/feed/post/", permit(per.PlatformReplyView), replyFeedProxyPost)
}
p := b.Group("/pprof")
{
p.GET("/profile", permit(per.PerformanceManager), buildSvg)
p.GET("/svg", permit(per.PerformanceManager), readSvg)
p.GET("/heap", permit(per.PerformanceManager), heap)
p.GET("/flame", permit(per.PerformanceManager), flame)
p.GET("/", permit(per.PerformanceManager), pprof)
}
ut := b.Group("/ut")
{
ut.GET("/merge/list", utList)
ut.GET("/detail/list", utDetail)
ut.GET("/history/commit", utHistoryCommit)
ut.GET("/rank/list", utRank)
ut.GET("/rank/user", userRank)
ut.GET("/quality/trend", utQATrend)
ut.GET("/commits", utGeneralCommit)
ut.GET("/dashboard/pkgs", utDashPkgsTree)
ut.GET("/dashboard/curve", utDashCurve)
ut.GET("/dashboard/histogram", utDashHistogram)
ut.GET("/dashboard/histogram/user", utDashUserDetail)
ut.GET("/app/list", utApps)
}
open := b.Group("/open")
{
open.GET("/get/", permit(per.OpenView), openProxyGet)
open.POST("/post/", permit(per.OpenView), openProxyPost)
}
}
// no auth
d := e.Group("x/admin/apm")
notAuth := d.Group("/")
{
notAuth.GET("canal/alarm", canalList) // 运维canal报警接口
notAuth.GET("databus/clusters", databusClusters)
notAuth.GET("databus/alarm", databusAlarm) // 运维databus告警用
notAuth.GET("databus/alarms", databusAlarms) // 有所有group diff查询时间巨长2分钟起板
notAuth.GET("ut/baseline", utBaseline)
notAuth.GET("noauth/discovery/fetch", discoveryProxyNoAuth) // 提供给自动告警查询对应实例
notAuth.GET("ecode", ecodeList)
notAuth.POST("databus/opsmind", databusOpsmind)
notAuth.POST("databus/opsmind/remove", databusOpsmindRemove)
notAuth.GET("databus/query", databusQuery)
notAuth.GET("ecode/get/ecodes", getEcodes)
notAuth.GET("ecode/get/prod/ecodes", getProdEcodes)
notAuth.GET("ecode/langs", codeLangsList)
}
dapper := d.Group("/dapper")
{
dapper.GET("/", dapperProxy)
}
up := d.Group("/ut")
{
up.POST("/upload", upload)
up.POST("/upload/app", uploadApp)
//up.GET("/tyrant", check)
up.GET("/check", check)
up.POST("/merge/set", utSetMerged)
up.GET("/dashboard/history/commit", dashHistoryCommit)
up.GET("/git/report", utGitReport)
}
m := d.Group("/monitor")
{
m.GET("/apps", appNameList)
m.GET("/prometheus", prometheusList)
m.GET("/broadcast", broadcastList)
m.GET("/databus", databusList)
m.GET("/online", onlineList)
}
warn := d.Group("/warn")
{
warn.POST("/active", activeWarning)
}
}
// Paper paper.
type Paper struct {
Total int `json:"total"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items interface{} `json:"items"`
}
// ping check server ok.
func ping(c *bm.Context) {
if err := apmSvc.Ping(c); err != nil {
c.AbortWithStatus(http.StatusServiceUnavailable)
log.Error("apm-admin service ping error(%v)", err)
}
}
func permit(rule string) bm.HandlerFunc {
return func(ctx *bm.Context) {
usernameI, _ := ctx.Get("username")
username, ok := usernameI.(string)
if !ok || username == "" {
ctx.JSON(nil, ecode.NoLogin)
ctx.Abort()
return
}
if rule == "" {
return
}
if err := apmSvc.Permit(ctx, username, rule); err != nil {
log.Error("apmSvc.Permit(%s, %s) error(%v)", username, rule, err)
ctx.JSON(nil, err)
ctx.Abort()
}
}
}

View File

@@ -0,0 +1,53 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
func appNameList(c *bm.Context) {
c.JSON(apmSvc.AppNameList(c), nil)
}
func prometheusList(c *bm.Context) {
v := new(struct {
AppName string `form:"app_name" validate:"required"`
Method string `form:"method" validate:"required"`
MType string `form:"mtype" default:"count"`
})
if err := c.Bind(v); err != nil {
return
}
pts, err := apmSvc.PrometheusList(c, v.AppName, v.Method, v.MType)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(pts, nil)
}
func onlineList(c *bm.Context) {
ols, err := apmSvc.OnlineList(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(ols, nil)
}
func broadcastList(c *bm.Context) {
bcs, err := apmSvc.BroadCastList(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(bcs, nil)
}
func databusList(c *bm.Context) {
dbs, err := apmSvc.DataBusList(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(dbs, nil)
}

View File

@@ -0,0 +1,140 @@
package http
import (
"context"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/need"
bm "go-common/library/net/http/blademaster"
)
// @params NListReq
// @router get /x/admin/apm/need/list
// @response NListResp
func needList(c *bm.Context) {
var (
infos []*need.NInfo
total int64
err error
)
username := name(c)
arg := new(need.NListReq)
if err = c.Bind(arg); err != nil {
return
}
if infos, total, err = apmSvc.NeedInfoList(c, arg, username); err != nil {
c.JSON(nil, err)
return
}
res := &need.NListResp{
Data: infos,
Total: total,
}
c.JSON(res, nil)
}
// @params NAddReq
// @router post /x/admin/apm/need/add
// @response EmpResp
func needAdd(c *bm.Context) {
var err error
username := name(c)
req := new(need.NAddReq)
if err = c.Bind(req); err != nil {
return
}
if err = apmSvc.NeedInfoAdd(c, req, username); err != nil {
c.JSON(nil, err)
return
}
go apmSvc.SendWeMessage(context.Background(), req.Title, need.VerifyType[need.NeedApply], "", username, conf.Conf.Superman)
go apmSvc.SendWeMessage(context.Background(), req.Title, need.VerifyType[need.NeedVerify], "", username, []string{username})
c.JSON(nil, err)
}
// @params NEditReq
// @router post /x/admin/apm/need/edit
// @response EmpResp
func needEdit(c *bm.Context) {
var err error
req := new(need.NEditReq)
if err = c.Bind(req); err != nil {
return
}
username := name(c)
if err = apmSvc.NeedInfoEdit(c, req, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
// @params NVerifyReq
// @router post /x/admin/apm/need/verify
// @response EmpResp
func needVerify(c *bm.Context) {
var (
err error
ni *need.NInfo
)
req := new(need.NVerifyReq)
if err = c.Bind(req); err != nil {
return
}
username := name(c)
if ni, err = apmSvc.NeedInfoVerify(c, req); err != nil {
c.JSON(nil, err)
return
}
go apmSvc.SendWeMessage(context.Background(), ni.Title, need.VerifyType[need.NeedReview], need.VerifyType[req.Status], username, []string{username})
c.JSON(nil, err)
}
// @params Likereq
// @router post /x/admin/apm/need/thumbsup
// @response EmpResp
func needThumbsUp(c *bm.Context) {
var err error
req := new(need.Likereq)
if err = c.Bind(req); err != nil {
return
}
username := name(c)
if err = apmSvc.NeedInfoVote(c, req, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
// @params Likereq
// @router get /x/admin/need/vote/list
// @response VoteListResp
func needVoteList(c *bm.Context) {
var (
votes []*need.UserLikes
total int64
err error
)
req := new(need.Likereq)
if err = c.Bind(req); err != nil {
return
}
if votes, total, err = apmSvc.NeedVoteList(c, req); err != nil {
c.JSON(nil, err)
return
}
res := &need.VoteListResp{
Data: votes,
Total: total,
}
c.JSON(res, nil)
}

View File

@@ -0,0 +1,108 @@
package http
import (
"fmt"
"net/url"
"testing"
"github.com/smartystreets/goconvey/convey"
"go-common/app/admin/main/apm/model/need"
)
var (
_nadduri = "%s/x/admin/apm/need/add"
_nlisturi = "%s/x/admin/apm/need/list"
_nedituri = "%s/x/admin/apm/need/edit"
_nverifyuri = "%s/x/admin/apm/need/verify"
_nthumsupuri = "%s/x/admin/apm/need/thumbsup"
_nvotelisturi = "%s/x/admin/apm/need/vote/list"
)
func TestNeedList(t *testing.T) {
convey.Convey("", t, func() {
params := url.Values{}
params.Set("pn", "1")
params.Set("ps", "5")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *need.NListResp `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_nlisturi, _domain), "", params, &res)
t.Logf("res%+v", res.Data)
})
}
func TestNeedAdd(t *testing.T) {
convey.Convey("TestNeedAdd normal", t, func() {
params := url.Values{}
params.Set("title", "dsds")
params.Set("content", "sds")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nadduri, _domain), "", params, &res)
t.Logf("res%+v", res)
convey.So(res.Code, convey.ShouldEqual, 0)
})
//convey.Convey("TestNeedAdd params error", t, func() {
// // params := url.Values{}
// // params.Set("title", "提一个小需求阿斯加德卡萨")
// // res := Response{}
// // _ = requests("POST", fmt.Sprintf(_nadduri, _domain), "", params, &res)
// // t.Logf("res%+v", res)
// // convey.So(res.Code, convey.ShouldEqual, -400)
// //})
}
func TestNeedEdit(t *testing.T) {
convey.Convey("TestNeedEdit", t, func() {
params := url.Values{}
params.Set("title", "fss")
params.Set("content", "fss")
params.Set("id", "26")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nedituri, _domain), "", params, &res)
convey.So(res.Code, convey.ShouldEqual, 0)
})
}
func TestNeedVerify(t *testing.T) {
convey.Convey("TestNeedVerify", t, func() {
params := url.Values{}
params.Set("status", "2")
params.Set("id", "28")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nverifyuri, _domain), "", params, &res)
convey.So(res.Code, convey.ShouldEqual, 70018)
})
}
func TestNeedThumbsUp(t *testing.T) {
convey.Convey("TestNeedThumbsUp", t, func() {
params := url.Values{}
params.Set("req_id", "29")
params.Set("like_type", "1")
res := Response{}
_ = requests("POST", fmt.Sprintf(_nthumsupuri, _domain), "", params, &res)
convey.So(res.Code, convey.ShouldEqual, 0)
})
}
func TestVoteList(t *testing.T) {
convey.Convey("TestVoteList", t, func() {
params := url.Values{}
params.Set("req_id", "11")
params.Set("like_type", "1")
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
Data *need.VoteListResp `json:"data"`
})
_ = requests("GET", fmt.Sprintf(_nvotelisturi, _domain), "", params, &res)
t.Logf("res%+v", res)
})
}

View File

@@ -0,0 +1,134 @@
package http
// import (
// "context"
// "encoding/json"
// "flag"
// "fmt"
// "net/http"
// "net/url"
// "strings"
// "testing"
// "time"
// "go-common/app/admin/main/apm/conf"
// "go-common/app/admin/main/apm/service"
// bm "go-common/library/net/http/context"
// )
// var path = "http://127.0.0.1:80/xx"
// type resp struct {
// http.ResponseWriter
// }
// func TestNotifyApply(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("cluster", "test_kafka_9092-266")
// params.Set("topic_name", "AccLabour-T")
// params.Set("remark", "test")
// params.Set("project", "main.web-svr")
// params.Set("topic_remark", "test")
// params.Set("offset", "new")
// params.Set("filter", "1")
// params.Set("concurrent", "10")
// params.Set("callback", `{"aa":1}`)
// params.Set("filters", `[{"field":"svv","condition":1,"value":"v"}]`)
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusNotifyApplyAdd(ctx)
// fmt.Println(ctx.Result())
// }
// func TestApplyList(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// // params.Set("cluster", "test_kafka_9092-266")
// // params.Set("topic_name", "AccAnswer-T")
// // params.Set("project", "main.web-svr")
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusApplyList(ctx)
// data, err := json.Marshal(ctx.Result())
// fmt.Println(string(data), err)
// }
// func TestNotifyList(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("cluster", "test_kafka_9092-266")
// params.Set("topic_name", "AccAnswer-T")
// params.Set("remark", "test")
// //params.Set("project", "main.web-svr")
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusNotifyList(ctx)
// data, err := json.Marshal(ctx.Result())
// fmt.Println(string(data), err)
// }
// func TestNotifyEdit(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("n_id", "159")
// params.Set("offset", "new")
// params.Set("filter", "0")
// params.Set("state", "0")
// params.Set("concurrent", "10")
// params.Set("callback", `{"aaq":1}`)
// params.Set("filters", `[{"id":4,"field":"test","condition":1,"value":"vvv"}]`)
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusNotifyEdit(ctx)
// data, err := json.Marshal(ctx.Result())
// fmt.Println(string(data), err)
// }
// func TestApplyProcess(t *testing.T) {
// flag.Set("conf", "../cmd/apm-admin-test.toml")
// conf.Init()
// apmSvc = service.New(conf.Conf)
// params := url.Values{}
// params.Set("id", "165")
// params.Set("state", "3")
// req, _ := http.NewRequest("POST", path, strings.NewReader(params.Encode()))
// req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.ParseForm()
// ctx := bm.NewContext(context.TODO(), req, resp{}, time.Second)
// ctx.Set("username", "haoguanwei")
// ctx.Request().ParseForm()
// //databusApplyApprovalProcess(ctx)
// fmt.Println(ctx.Result())
// }

View File

@@ -0,0 +1,38 @@
package http
import (
"strings"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func openProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/open/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.OpenProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/open/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func openProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/open/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.OpenProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/open/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,158 @@
package http
import (
"strings"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func searchProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/search/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/search/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func searchProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/search/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/search/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/reply/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/reply/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func tagProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/tag/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/tag/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func tagProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/tag/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/tag/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func bfsProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/bfs/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/bfs/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func bfsProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/bfs/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/bfs/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyFeedProxyGet(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/feed/get/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "GET", req.URL.Path[idx+len("/x/admin/apm/platform/reply/feed/get/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func replyFeedProxyPost(c *bm.Context) {
req := c.Request
idx := strings.Index(req.URL.Path, "/x/admin/apm/platform/reply/feed/post/")
if idx == -1 {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := apmSvc.PlatformProxy(c, "POST", req.URL.Path[idx+len("/x/admin/apm/platform/reply/feed/post/"):], req.Form)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,155 @@
package http
import (
"io/ioutil"
"net/http"
"go-common/app/admin/main/apm/conf"
mpprof "go-common/app/admin/main/apm/model/pprof"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func buildSvg(c *bm.Context) {
v := new(struct {
URL string `form:"url" validate:"required"`
URI string `form:"uri" validate:"required"`
SvgName string `form:"name" validate:"required"`
Time int64 `form:"time" validate:"required"`
HostName string `form:"hostname" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
if !(v.URI == "profile" || v.URI == "heap") {
c.JSON(nil, ecode.RequestErr)
return
}
err = apmSvc.Pprof(v.URL, v.URI, v.SvgName, v.HostName, v.Time, 2)
c.JSON(nil, err)
}
func readSvg(c *bm.Context) {
v := new(struct {
SvgName string `form:"name" validate:"required"`
URI string `form:"uri" validate:"required"`
HostName string `form:"hostname" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
url := conf.Conf.Pprof.Dir + "/" + v.SvgName + "_" + v.HostName + "_" + v.URI + ".svg"
data, err := ioutil.ReadFile(url)
if err != nil {
log.Error("readfile error(%v)", err)
c.JSON(nil, err)
return
}
c.Bytes(http.StatusOK, "image/svg+xml; charset=utf-8", data)
}
func heap(c *bm.Context) {
v := new(struct {
URL string `form:"url" validate:"required"`
URI string `form:"uri" validate:"required"`
SvgName string `form:"name" validate:"required"`
HostName string `form:"hostname" validate:"required"`
})
var err error
var data []byte
if err = c.Bind(v); err != nil {
return
}
if v.URI != "heap" {
c.JSON(nil, ecode.RequestErr)
return
}
err = apmSvc.Pprof(v.URL, v.URI, v.SvgName, v.HostName, 1, 1)
if err != nil {
c.JSON(nil, err)
return
}
url := conf.Conf.Pprof.Dir + "/" + v.SvgName + "_" + v.HostName + "_" + v.URI + ".svg"
data, err = ioutil.ReadFile(url)
if err != nil {
log.Error("readfile error(%v)", err)
c.JSON(nil, err)
return
}
c.Bytes(http.StatusOK, "image/svg+xml; charset=utf-8", data)
}
func flame(c *bm.Context) {
v := new(struct {
URL string `form:"url" validate:"required"`
URI string `form:"uri" validate:"required"`
SvgName string `form:"name" validate:"required"`
Time int64 `form:"time"`
HostName string `form:"hostname" validate:"required"`
})
var err error
var data []byte
if err = c.Bind(v); err != nil {
return
}
if !(v.URI == "profile" || v.URI == "heap") {
c.JSON(nil, ecode.RequestErr)
return
}
if v.URI == "heap" {
err = apmSvc.Torch(c, v.URL, v.URI, v.SvgName, v.HostName, 1, 1)
if err != nil {
c.JSON(nil, err)
return
}
url := conf.Conf.Pprof.Dir + "/" + v.SvgName + "_" + v.HostName + "_" + v.URI + "_flame.svg"
data, err = ioutil.ReadFile(url)
if err != nil {
log.Error("readfile error(%v)", err)
c.JSON(nil, err)
return
}
c.Bytes(http.StatusOK, "image/svg+xml; charset=utf-8", data)
} else {
err = apmSvc.Torch(c, v.URL, v.URI, v.SvgName, v.HostName, v.Time, 2)
c.JSON(nil, err)
}
}
func activeWarning(c *bm.Context) {
// var (
// err error
// body []byte
// )
// if body, err = ioutil.ReadAll(c.Request.Body); err != nil {
// c.JSON(nil, fmt.Errorf("warning body empty"))
// return
// }
// if err = apmSvc.ActiveWarning(c, string(body)); err != nil {
// c.JSON(nil, err)
// return
// }
// ioutil.ReadAll You need close body.
c.JSON(nil, nil)
}
func pprof(c *bm.Context) {
var (
err error
pws = make([]*mpprof.Warn, 0)
req = &mpprof.Params{}
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if pws, err = apmSvc.PprofWarn(c, req); err != nil {
c.JSON(nil, err)
return
}
c.JSON(pws, nil)
}

View File

@@ -0,0 +1,139 @@
package http
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
type result struct {
Code int `gorm:"column:code" json:"code"`
Message string `gorm:"column:message" json:"message"`
}
//http client
func httpDo(method, uri, cookie string, params url.Values) (data *result, err error) {
client := &http.Client{}
req, err := http.NewRequest(method, uri, strings.NewReader(params.Encode()))
if err != nil {
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Cookie", cookie)
resp, err := client.Do(req)
if err != nil {
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
defer resp.Body.Close()
data = &result{}
json.Unmarshal(body, data)
return
}
func TestHttpDo(t *testing.T) {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
params := url.Values{"id": {"20"}, "state": {"3"}}
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=429fca48067ef8234335cddda8a7d64ba46662e3d9448d38df6184f63a37e165"
t.Error("print log")
if res, err := httpDo("POST", uri, cookie, params); err != nil {
fmt.Println("There are some error~")
fmt.Printf("%s", err)
} else {
fmt.Println("code:", res.Code)
fmt.Println("message:", res.Message)
}
}
func TestProcess(t *testing.T) {
Convey("if apply.State == 1, state =[2,3,4]; expect: code ==0", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"7"}, "state": {"2"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, 0)
}
})
}
func TestProcess2(t *testing.T) {
Convey("if apply.State == 2, state =[2,3,4]; expect: code ==0", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"8"}, "state": {"3"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, 0)
}
})
}
func TestProcess3(t *testing.T) {
Convey("if apply.State == 3, state =[2,3,4]; expect: code == -400", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"9"}, "state": {"2"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, -400)
So(res.Message, ShouldEqual, "只有申请中和打回才可审核")
}
})
}
func TestProcess4(t *testing.T) {
Convey("if apply.State == 4, state =[2,3,4]; expect: code == -400", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"10"}, "state": {"2"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, -400)
So(res.Message, ShouldEqual, "只有申请中和打回才可审核")
}
})
}
func TestProcess5(t *testing.T) {
Convey("if apply.State == 1, state !=[2,3,4]; expect: code == -400", t, func() {
uri := "http://127.0.0.1:7331/x/admin/apm/canal/apply/approval/process"
cookie := "username=hedan; _AJSESSIONID=d9dde52c35e2e0389fd8c345873c7d22; sven-apm=f78e8fadc7f41048258acf43f5e9abee59f7b7a5bb6312b81fd31a21945fd21e"
params := url.Values{"id": {"11"}, "state": {"5"}}
res, err := httpDo("POST", uri, cookie, params)
if err != nil {
t.Error(err)
} else {
So(res.Code, ShouldEqual, -400)
So(res.Message, ShouldEqual, "state值范围2,3,4")
}
})
}

View File

@@ -0,0 +1,61 @@
package http
import (
"go-common/app/admin/main/apm/model/ut"
bm "go-common/library/net/http/blademaster"
)
// @params RankReq
// @router get /x/admin/apm/ut/rank/list
// @response RankResp
func utRank(c *bm.Context) {
var (
err error
topTens []*ut.RankResp
bottomTens []*ut.RankResp
rankList = make(map[string]interface{})
UserList *ut.RankResp
)
v := new(struct {
UserName string `form:"username"`
})
if err = c.Bind(v); err != nil {
return
}
if topTens, err = apmSvc.RankTen(c, "desc"); err != nil {
c.JSON(nil, err)
return
}
if bottomTens, err = apmSvc.RankTen(c, "asc"); err != nil {
c.JSON(nil, err)
return
}
if UserList, err = apmSvc.UserRank(c, v.UserName); err != nil {
c.JSON(nil, err)
return
}
rankList["topten"] = topTens
rankList["bottomten"] = bottomTens
rankList["user"] = UserList
c.JSON(rankList, nil)
}
// /x/admin/apm/ut/rank/user
func userRank(c *bm.Context) {
var (
err error
UserList *ut.RankResp
)
v := new(struct {
UserName string `form:"username"`
})
if err = c.Bind(v); err != nil {
return
}
if UserList, err = apmSvc.UserRank(c, v.UserName); err != nil {
c.JSON(nil, err)
return
}
c.JSON(UserList, nil)
}

View File

@@ -0,0 +1,732 @@
{
"swagger": "2.0",
"info": {
"title": "go-common api",
"description": "api",
"version": "1.0",
"contact": {
"email": "lintanghui@bilibili.com"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"paths": {
"/x/admin/apm/need/add": {
"post": {
"operationId": "/x/admin/apm/need/add",
"parameters": [
{
"in": "query",
"name": "title",
"required": true,
"type": "string"
},
{
"in": "query",
"name": "content",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/edit": {
"post": {
"operationId": "/x/admin/apm/need/edit",
"parameters": [
{
"in": "query",
"name": "content",
"type": "string"
},
{
"in": "query",
"name": "id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "title",
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/list": {
"get": {
"operationId": "/x/admin/apm/need/list",
"parameters": [
{
"in": "query",
"name": "ps",
"description": " 默认值 20",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "pn",
"description": " 默认值 1",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "status",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "reporter",
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/NListResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/thumbsup": {
"post": {
"operationId": "/x/admin/apm/need/thumbsup",
"parameters": [
{
"in": "query",
"name": "like_type",
"type": "integer",
"format": "int32"
},
{
"in": "query",
"name": "req_id",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/need/verify": {
"post": {
"operationId": "/x/admin/apm/need/verify",
"parameters": [
{
"in": "query",
"name": "id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "status",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/EmpResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/ut/detail/list": {
"get": {
"operationId": "/x/admin/apm/ut/detail/list",
"parameters": [
{
"in": "query",
"name": "merge_id",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "commit_id",
"type": "string"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/Detail",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/ut/history/commit": {
"get": {
"operationId": "/x/admin/apm/ut/history/commit",
"parameters": [
{
"in": "query",
"name": "merge_id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "commit_id",
"type": "string"
},
{
"in": "query",
"name": "pn",
"description": " 默认值 1",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "ps",
"description": " 默认值 20",
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/HistoryCommitResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/apm/ut/info/list": {
"get": {
"operationId": "/x/admin/apm/ut/info/list",
"parameters": [
{
"in": "query",
"name": "merge_id",
"description": " 默认值 0",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "username",
"type": "string"
},
{
"in": "query",
"name": "pn",
"description": " 默认值 1",
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "ps",
"description": " 默认值 20",
"type": "integer",
"format": "int64"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/Paper",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
},
"/x/admin/need/vote/list": {
"get": {
"operationId": "/x/admin/need/vote/list",
"parameters": [
{
"in": "query",
"name": "req_id",
"required": true,
"type": "integer",
"format": "int64"
},
{
"in": "query",
"name": "like_type",
"type": "integer",
"format": "int32"
}
],
"responses": {
"200": {
"description": "服务成功响应内容",
"schema": {
"type": "object",
"properties": {
"code": {
"description": "错误码描述",
"type": "integer"
},
"data": {
"$ref": "#/definitions/VoteListResp",
"type": "object"
},
"message": {
"description": "错误码文本描述",
"type": "string"
},
"ttl": {
"description": "客户端限速时间",
"type": "integer",
"format": "int64"
}
}
}
}
}
}
}
},
"definitions": {
"Detail": {
"title": "Detail",
"description": "Detail ut_detail",
"type": "object",
"properties": {
"Assertions": {
"type": "integer",
"format": "int64"
},
"CTime": {
"type": "string",
"format": "string"
},
"CommitID": {
"type": "string"
},
"Coverage": {
"type": "string"
},
"Failures": {
"type": "integer",
"format": "int64"
},
"HTMLURL": {
"type": "string"
},
"ID": {
"type": "integer",
"format": "int64"
},
"MTime": {
"type": "string",
"format": "string"
},
"MergeID": {
"type": "integer",
"format": "int64"
},
"PKG": {
"type": "string"
},
"Panics": {
"type": "integer",
"format": "int64"
},
"PassRate": {
"type": "string"
},
"Passed": {
"type": "integer",
"format": "int64"
},
"ReportURL": {
"type": "string"
},
"Skipped": {
"type": "integer",
"format": "int64"
},
"Username": {
"type": "string"
}
}
},
"EmpResp": {
"title": "EmpResp",
"description": "EmpResp is empty resp.",
"type": "object"
},
"HistoryCommitResp": {
"title": "HistoryCommitResp",
"description": "HistoryCommitResp struct",
"type": "object",
"properties": {
"Assertions": {
"type": "integer",
"format": "int64"
},
"CommitID": {
"type": "string"
},
"CovChange": {
"type": "string"
},
"Coverage": {
"type": "string"
},
"Failures": {
"type": "integer",
"format": "int64"
},
"ID": {
"type": "integer",
"format": "int64"
},
"MergeID": {
"type": "integer",
"format": "int64"
},
"Panics": {
"type": "integer",
"format": "int64"
},
"PassRate": {
"type": "string"
},
"Passed": {
"type": "integer",
"format": "int64"
},
"Skipped": {
"type": "integer",
"format": "int64"
}
}
},
"NInfo": {
"title": "NInfo",
"description": "NInfo struct",
"type": "object",
"properties": {
"CTime": {
"type": "string",
"format": "string"
},
"Content": {
"type": "string"
},
"DislikeCounts": {
"type": "integer",
"format": "int64"
},
"ID": {
"type": "integer",
"format": "int64"
},
"LikeCounts": {
"type": "integer",
"format": "int64"
},
"LikeState": {
"type": "integer",
"format": "int32"
},
"MTime": {
"type": "string",
"format": "string"
},
"Reporter": {
"type": "string"
},
"Status": {
"type": "integer",
"format": "int32"
},
"Title": {
"type": "string"
}
}
},
"NListResp": {
"title": "NListResp",
"description": "NListResp is list resp struct",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": {
"$ref": "#/definitions/NInfo",
"type": "object"
}
},
"Total": {
"type": "integer",
"format": "int64"
}
}
},
"Paper": {
"title": "Paper",
"description": "Paper canallist resp",
"type": "object",
"properties": {
"Items": {
"$ref": "#/definitions/false",
"type": "object"
},
"Pn": {
"type": "integer",
"format": "int64"
},
"Ps": {
"type": "integer",
"format": "int64"
},
"Total": {
"type": "integer",
"format": "int64"
}
}
},
"UserLikes": {
"title": "UserLikes",
"description": "UserLikes struct",
"type": "object",
"properties": {
"CTime": {
"type": "string",
"format": "string"
},
"ID": {
"type": "integer",
"format": "int64"
},
"LikeType": {
"type": "integer",
"format": "int32"
},
"MTime": {
"type": "string",
"format": "string"
},
"ReqID": {
"type": "integer",
"format": "int64"
},
"User": {
"type": "string"
}
}
},
"VoteListResp": {
"title": "VoteListResp",
"description": "VoteListResp is vote resp struct",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": {
"$ref": "#/definitions/UserLikes",
"type": "object"
}
},
"Total": {
"type": "integer",
"format": "int64"
}
}
},
"false": null
}
}

View File

@@ -0,0 +1,135 @@
package http
import (
"encoding/json"
"io/ioutil"
"mime/multipart"
"time"
"go-common/app/admin/main/apm/model/ut"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func upload(c *bm.Context) {
var (
file multipart.File
body []byte
htmlURL string
reportURL string
dataURL string
err error
pkg = new(ut.PkgAnls)
files []*ut.File
res = &ut.UploadRes{}
header *multipart.FileHeader
)
c.Request.ParseMultipartForm(32 << 20)
if err = c.Bind(res); err != nil {
return
}
log.Info("ut.upload(%d) start! current_time(%d)", res.MergeID, time.Now().Unix())
defer log.Info("ut.upload(%d) finished. current_time(%d)", res.MergeID, time.Now().Unix())
if file, _, err = c.Request.FormFile("report_file"); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("report request upload err (%v)", err)
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("ioutil.ReadAll(c.Request().Body) error(%v)", err)
return
}
if body, err = apmSvc.ParseContent(c, body); err != nil {
c.JSON(err.Error(), err)
return
}
if pkg, err = apmSvc.CalcCount(c, body); err != nil {
c.JSON(nil, err)
return
}
if pkg.Assertions == 0 {
c.JSON("no result", nil)
return
}
if reportURL, err = apmSvc.Upload(c, "json", time.Now().Unix(), body); err != nil {
c.JSON(nil, err)
return
}
if file, header, err = c.Request.FormFile("data_file"); err == nil && header.Size > 0 {
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("Upload data request error(%v)", err)
return
}
if files, err = apmSvc.CalcCountFiles(c, res, body); err != nil {
c.JSON(nil, err)
log.Error("Upload data calcCount error(%v)", err)
return
}
if dataURL, err = apmSvc.Upload(c, "text/plain", time.Now().Unix(), body); err != nil {
c.JSON(nil, err)
return
}
}
if file, _, err = c.Request.FormFile("html_file"); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("html request upload err (%v)", err)
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("html read error(%v)", err)
return
}
if htmlURL, err = apmSvc.Upload(c, "html", time.Now().Unix(), body); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.AddUT(c, pkg, files, res, dataURL, reportURL, htmlURL); err != nil {
c.JSON(nil, err)
return
}
// update ut_app has_ut = 1 && converage
if err = apmSvc.UpdateUTApp(c, pkg); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
// uploadApp upload path to ut_app
func uploadApp(c *bm.Context) {
var (
file multipart.File
body []byte
apps []*ut.App
err error
)
c.Request.ParseMultipartForm(32 << 20)
if file, _, err = c.Request.FormFile("path_file"); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("path request upload error(%v)", err)
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("path_file read error(%v)", err)
return
}
if err = json.Unmarshal(body, &apps); err != nil {
log.Error("json.Unmarshal error(%v)", err)
return
}
if err = apmSvc.AddUTApp(c, apps); err != nil {
c.JSON(nil, ecode.RequestErr)
log.Error("apmSvc.AddUtApp error(%v)", err)
return
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,35 @@
package http
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func Test(t *testing.T) {
convey.Convey("upload", t, func() {
url := "http://127.0.0.1:7331/x/admin/apm/ut/upload"
payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; " +
"name=\"html_file\"\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; " +
"name=\"mid\"\r\n\r\n6\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; " +
"name=\"username\"\r\n\r\nchengxing\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: " +
"form-data; name=\"report_file\"\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
req.Header.Add("Cookie", "_AJSESSIONID=cf81d40c0e9d960a0ce89ceeb05c5670; username=chengxing; "+
"sven-apm=4104f6b8cb1d967a0dd45d6934638ba2bfc86cd239bf7bab095b8a1cc3f85b65")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Cache-Control", "no-cache")
req.Header.Add("Postman-Token", "69b1317b-0b01-43a0-a85d-c899f64ae34e")
res, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(res.Body)
defer res.Body.Close()
fmt.Println(string(body))
})
}

View File

@@ -0,0 +1,788 @@
package http
import (
"strings"
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/user"
"go-common/library/conf/env"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
func name(ctx *bm.Context) (name string) {
usernameI, _ := ctx.Get("username")
name, _ = usernameI.(string)
return
}
func userAuth(c *bm.Context) {
var (
usr = &user.User{}
username = name(c)
err error
mdls []*user.Module
rls []*user.Rule
super bool
)
if usr, err = apmSvc.GetUser(c, username); err != nil {
log.Error("apmSvc.userAuth error(%v)", err)
c.JSON(nil, err)
return
}
// err := apmSvc.DB.Where("username = ?", username).First(usr).Error
// if err == gorm.ErrRecordNotFound {
// usr.UserName = username
// usr.NickName = username
// err = apmSvc.DB.Create(usr).Error
// }
// if err != nil {
// log.Error("apmSvc.userAuth error(%v)", err)
// c.JSON(nil, err)
// return
// }
for _, u := range conf.Conf.Superman {
if u == username {
super = true
break
}
}
var (
ms []string
rs []string
)
if super {
for m := range user.Modules {
ms = append(ms, m)
for rl := range user.Rules {
if strings.HasPrefix(rl+"_", m) {
rs = append(rs, rl)
}
}
}
} else {
ms, rs = apmSvc.GetDefaultPermission(c)
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.userAuth modules error(%v)", err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil {
log.Error("apmSvc.userAuth rules error(%v)", err)
c.JSON(nil, err)
return
}
for _, m := range mdls {
ms = append(ms, m.Module)
}
for _, r := range rls {
rs = append(rs, r.Rule)
}
}
data := user.Result{
Super: super,
User: usr,
Env: env.DeployEnv,
Rules: append(ms, rs...),
}
c.JSON(data, nil)
}
func userRuleStates(c *bm.Context) {
username := name(c)
usr := &user.User{}
err := apmSvc.DB.Where("username = ?", username).First(usr).Error
if err != nil {
log.Error("apmSvc.userRuleStates error(%v)", err)
c.JSON(nil, err)
return
}
for _, u := range conf.Conf.Superman {
if u == username {
c.JSONMap(map[string]interface{}{
"message": "超级管理员拥有所有权限",
}, nil)
return
}
}
var (
//app *user.Apply
rls []*user.Rule
)
app := &user.Apply{}
if err = apmSvc.DB.Where("user_id=? AND status=?", usr.ID, 1).First(app).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("apm.Svc.userRuleStates error(%v)", err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("apm.Svc.userRuleStates error(%v)", err)
c.JSON(nil, err)
return
}
trs := strings.Split(app.Rules, ",")
type ruleRes struct {
Rule string `json:"rule"`
Name string `json:"name"`
State int `json:"state"`
}
data := map[string][]*ruleRes{}
for module := range user.Modules {
if env.DeployEnv != env.DeployEnvProd && module == "CONFIG" {
continue
}
if user.Modules[module].Permit == user.PermitSuper {
continue
}
// if module == "USER" {
// continue
// }
NEXTRULE:
for rule := range user.Rules {
if !strings.HasPrefix(rule, module) {
continue
}
rr := &ruleRes{Rule: rule, Name: user.Rules[rule].Des, State: 0}
_, rdft := apmSvc.GetDefaultPermission(c)
for _, rl := range rdft {
if rule == rl {
rr.State = 1
data[module] = append(data[module], rr)
continue NEXTRULE
}
}
for _, rl := range rls {
if rule == rl.Rule {
rr.State = 1
data[module] = append(data[module], rr)
continue NEXTRULE
}
}
for _, tr := range trs {
if rule == tr {
rr.State = 2
data[module] = append(data[module], rr)
continue NEXTRULE
}
}
data[module] = append(data[module], rr)
}
}
c.JSON(map[string]interface{}{
"user": usr,
"rule_states": data,
}, nil)
}
func userApply(c *bm.Context) {
username := name(c)
usr := &user.User{}
if err := apmSvc.DB.Where("username = ?", username).First(usr).Error; err != nil {
log.Error("apmSvc.userApply error(%v)", err)
c.JSON(nil, err)
return
}
v := new(struct {
Rules []string `form:"rules,split" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
for _, rule := range v.Rules {
if _, ok := user.Rules[rule]; !ok {
c.JSONMap(map[string]interface{}{
"message": "申请的操作不存在",
}, nil)
return
}
}
istr := strings.Join(v.Rules, ",")
m := &user.Apply{
UserID: usr.ID,
Rules: istr,
Status: 1,
}
db := apmSvc.DB.Model(&user.Apply{}).Create(m)
if err := db.Error; err != nil {
log.Error("apmSvc.userApply error(%v)", err)
c.JSON(nil, err)
return
}
c.JSONMap(map[string]interface{}{
"message": "申请成功",
}, nil)
}
func userApplyEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Rules []string `form:"rules,split" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
for _, r := range v.Rules {
if _, ok := user.Rules[r]; !ok {
c.JSONMap(map[string]interface{}{
"message": "申请的操作不存在",
}, nil)
return
}
}
username := name(c)
if err = apmSvc.DB.Model(&user.Apply{}).Where("status = 1 AND id = ?", v.ID).Update(map[string]interface{}{
"rules": strings.Join(v.Rules, ","), "admin": username}).Error; err != nil {
log.Error("apmSvc.userApplyEdit error(%v)", err)
c.JSON(nil, err)
return
}
c.JSONMap(map[string]interface{}{
"message": "修改成功",
}, nil)
}
func userAudit(c *bm.Context) {
username := name(c)
super := false
for _, u := range conf.Conf.Superman {
if u == username {
super = true
break
}
}
if !super {
c.JSON(nil, ecode.AccessDenied)
return
}
v := new(struct {
ID int64 `form:"id" validate:"required"`
Status int8 `form:"status" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if !(v.Status == 2 || v.Status == 3) {
log.Error("apmSvc.userAudit error(%v)", v.Status)
c.JSONMap(map[string]interface{}{
"message": "status值范围为23",
}, ecode.RequestErr)
return
}
if err := apmSvc.DB.Model(&user.Apply{}).Where("id = ? AND status = ?", v.ID, 1).Updates(map[string]interface{}{"status": v.Status, "admin": username}).Error; err != nil {
log.Error("apmSvc.userAudit update user_apply error(%v)", err)
c.JSON(nil, err)
return
}
if v.Status == 3 {
c.JSONMap(map[string]interface{}{
"message": "权限审核不通过",
}, nil)
return
}
apps := &user.Apply{}
if err := apmSvc.DB.Where("id=?", v.ID).First(apps).Error; err != nil {
log.Error("apmSvc.userAudit find user_apply error(%v)", err)
c.JSON(nil, err)
return
}
rules := strings.Split(apps.Rules, ",")
for _, rule := range rules {
r := &user.Rule{}
apmSvc.DB.FirstOrCreate(r, &user.Rule{UserID: apps.UserID, Rule: rule})
for module := range user.Modules {
if strings.HasPrefix(rule, module) {
m := &user.Module{}
apmSvc.DB.FirstOrCreate(m, &user.Module{UserID: apps.UserID, Module: module})
}
}
}
c.JSONMap(map[string]interface{}{
"message": "权限审核通过",
}, nil)
}
func userApplies(c *bm.Context) {
username := name(c)
v := new(struct {
Pn int `form:"pn" default:"1" validate:"min=1"`
Ps int `form:"ps" default:"20" validate:"min=1"`
Name string `form:"name"`
})
err := c.Bind(v)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
var (
super bool
total int
applies []*user.Applies
)
for _, u := range conf.Conf.Superman {
if u == username {
super = true
break
}
}
if !super {
c.JSON(nil, ecode.AccessDenied)
return
}
if v.Name != "" {
err = apmSvc.DB.Raw(`SELECT user_apply.id, user_apply.user_id,user.username,user_apply.rules,user_apply.status
FROM user_apply LEFT JOIN user ON user_apply.user_id=user.id WHERE user_apply.status=? AND (user.username like ? OR user.nickname like ?)`,
1, "%"+v.Name+"%", "%"+v.Name+"%").Order("user_apply.id desc").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&applies).Error
} else {
err = apmSvc.DB.Raw(`SELECT user_apply.id, user_apply.user_id,user.username,user_apply.rules,user_apply.status
FROM user_apply LEFT JOIN user ON user_apply.user_id=user.id WHERE user_apply.status=?`,
1).Order("user_apply.id desc").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&applies).Error
}
// err := apmSvc.DB.Raw(`SELECT user_apply.id, user_apply.user_id,user.username,user_apply.rules,user_apply.status
// FROM user_apply LEFT JOIN user ON user_apply.user_id=user.id WHERE user_apply.status=?`, 1).Scan(&applies).Error
if err == gorm.ErrRecordNotFound {
c.JSONMap(map[string]interface{}{
"message": "当前没有任何申请",
}, nil)
return
}
if v.Name != "" {
err = apmSvc.DB.Model(&user.Apply{}).Joins("LEFT JOIN user ON user_apply.user_id=user.id").Where(`user_apply.status=?
AND (user.username like ? OR user.nickname like ?)`, 1, "%"+v.Name+"%", "%"+v.Name+"%").Count(&total).Error
} else {
err = apmSvc.DB.Model(&user.Apply{}).Joins(`LEFT JOIN user ON user_apply.user_id=user.id`).Where(`user_apply.status=?`, 1).Count(&total).Error
}
if err != nil {
log.Error("apmSvc.userApplies error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: applies,
Total: total,
}
c.JSON(data, nil)
}
func userList(c *bm.Context) {
v := new(struct {
Pn int `form:"pn" default:"1" validate:"min=1"`
Ps int `form:"ps" default:"20" validate:"min=1"`
Name string `form:"name"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
var (
pts []*user.User
total int
)
s := "%" + v.Name + "%"
if v.Name != "" {
err = apmSvc.DB.Where("username LIKE ? OR nickname LIKE ?", s, s).Order("id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&pts).Error
} else {
err = apmSvc.DB.Order("id").Offset((v.Pn - 1) * v.Ps).Limit(v.Ps).Find(&pts).Error
}
if err != nil {
log.Error("apmSvc.Users error(%v)", err)
c.JSON(nil, err)
return
}
if v.Name != "" {
err = apmSvc.DB.Where("username LIKE ? OR nickname LIKE ?", s, s).Model(&user.User{}).Count(&total).Error
} else {
err = apmSvc.DB.Model(&user.User{}).Count(&total).Error
}
if err != nil {
log.Error("apmSvc.Users count error(%v)", err)
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: pts,
Total: total,
}
c.JSON(data, nil)
}
func userInfo(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
log.Error("apmSvc.userInfo error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(usr, nil)
}
func userEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Nickname string `form:"nickname"`
Email string `form:"email"`
Phone string `form:"phone"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Model(&user.User{}).Where("id = ?", v.ID).Omit("id").UpdateColumns(v).Error; err != nil {
log.Error("apmSvc.userEdit error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "update",
"Where": "id = ?",
"Value1": v.ID,
"Update": v,
"Old": usr,
}
username := name(c)
apmSvc.SendLog(*c, username, 0, 2, int64(v.ID), "apmSvc.userEdit", sqlLog)
c.JSON(nil, err)
}
func userModules(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
log.Error("apmSvc.userInfo error(%v)", err)
c.JSON(nil, err)
return
}
var mdls []*user.Module
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.userAuth modules error(%v)", err)
c.JSON(nil, err)
return
}
var ms []string
for _, m := range mdls {
ms = append(ms, m.Module)
}
allMds := make(map[string]string)
for module := range user.Modules {
allMds[module] = user.Modules[module].Des
}
data := map[string]interface{}{
"owns": ms,
"modules": allMds,
}
c.JSON(data, nil)
}
func userRules(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
log.Error("apmSvc.userInfo error(%v)", err)
c.JSON(nil, err)
return
}
var (
mdls []*user.Module
rls []*user.Rule
)
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.userAuth modules error(%v)", err)
c.JSON(nil, err)
return
}
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil {
log.Error("apmSvc.userAuth rules error(%v)", err)
c.JSON(nil, err)
return
}
var rs []string
for _, r := range rls {
rs = append(rs, r.Rule)
}
allRls := map[string]string{}
for _, mdl := range mdls {
for rl, rlM := range user.Rules {
if strings.HasPrefix(rl+"_", mdl.Module) {
allRls[rl] = rlM.Des
}
}
}
data := map[string]interface{}{
"owns": rs,
"rules": allRls,
}
c.JSON(data, nil)
}
func userModulesEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Modules []string `form:"modules,split"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
var mdls []*user.Module
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.moduleEdit modules error(%v)", err)
c.JSON(nil, err)
return
}
var (
ns []*user.Module
ds []string
)
for _, m := range v.Modules {
if len(mdls) == 0 {
ns = append(ns, &user.Module{UserID: usr.ID, Module: m})
continue
}
for j, mdl := range mdls {
if m == mdl.Module {
break
}
if j+1 == len(mdls) {
ns = append(ns, &user.Module{UserID: usr.ID, Module: m})
}
}
}
for _, mdl := range mdls {
if len(v.Modules) == 0 {
ds = append(ds, mdl.Module)
continue
}
for j, m := range v.Modules {
if m == mdl.Module {
break
}
if j+1 == len(v.Modules) {
ds = append(ds, mdl.Module)
}
}
}
if err = apmSvc.DB.Exec("DELETE FROM user_module WHERE user_id=? AND module IN (?)", usr.ID, ds).Error; err != nil {
log.Error("apmSvc.moduleEdit delModule error(%v)", err)
c.JSON(nil, err)
return
}
var sqlLogs []*map[string]interface{}
sqlLog := &map[string]interface{}{
"SQLType": "delete",
"Where": "DELETE FROM user_module WHERE user_id=? AND module IN (?)",
"Value1": usr.ID,
"Value2": ds,
"Update": "",
"Old": "",
}
sqlLogs = append(sqlLogs, sqlLog)
username := name(c)
// apmSvc.SendLog(c, username, 0, 2, int64(v.ID), "apmSvc.moduleEdit", sqlLog)
for _, d := range ds {
if err = apmSvc.DB.Exec("DELETE FROM user_rule WHERE user_id=? AND rule LIKE ?", usr.ID, d+"_%").Error; err != nil {
log.Error("apmSvc.moduleEdit delModule error(%v)", err)
c.JSON(nil, err)
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.moduleEdit", sqlLogs)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "delete",
"Where": "DELETE FROM user_rule WHERE user_id=? AND rule LIKE ?",
"Value1": usr.ID,
"Value2": d + "_%",
"Update": "",
"Old": "",
}
sqlLogs = append(sqlLogs, sqlLog)
}
for _, n := range ns {
if err = apmSvc.DB.Create(n).Error; err != nil {
log.Error("apmSvc.moduleEdit addModule error(%v)", err)
c.JSON(nil, err)
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.moduleEdit", sqlLogs)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "add",
"Content": n,
}
sqlLogs = append(sqlLogs, sqlLog)
}
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.moduleEdit", sqlLogs)
c.JSON(nil, err)
}
func userRulesEdit(c *bm.Context) {
v := new(struct {
ID int64 `form:"id" validate:"required"`
Rules []string `form:"rules,split"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
usr := &user.User{}
if err = apmSvc.DB.First(usr, v.ID).Error; err != nil {
c.JSON(nil, err)
return
}
var mdls []*user.Module
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&mdls).Error; err != nil {
log.Error("apmSvc.moduleEdit modules error(%v)", err)
c.JSON(nil, err)
return
}
if len(mdls) == 0 {
log.Error("apmSvc.moduleEdit have not module error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
for _, rl := range v.Rules {
var has bool
for _, mdl := range mdls {
if has = strings.HasPrefix(rl, mdl.Module); has {
break
}
}
if !has {
log.Error("apmSvc.moduleEdit have not module error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
}
var rls []*user.Rule
if err = apmSvc.DB.Where("user_id=?", usr.ID).Find(&rls).Error; err != nil {
log.Error("apmSvc.ruleEdit modules error(%v)", err)
c.JSON(nil, err)
return
}
var (
ns []*user.Rule
ds []string
)
for _, m := range v.Rules {
if len(rls) == 0 {
ns = append(ns, &user.Rule{UserID: usr.ID, Rule: m})
continue
}
for j, rl := range rls {
if m == rl.Rule {
break
}
if j+1 == len(rls) {
ns = append(ns, &user.Rule{UserID: usr.ID, Rule: m})
}
}
}
for _, rl := range rls {
if len(v.Rules) == 0 {
ds = append(ds, rl.Rule)
continue
}
for j, m := range v.Rules {
if m == rl.Rule {
break
}
if j+1 == len(v.Rules) {
ds = append(ds, rl.Rule)
}
}
}
var sqlLogs []*map[string]interface{}
if err = apmSvc.DB.Exec("DELETE FROM user_rule WHERE user_id=? AND rule IN (?)", usr.ID, ds).Error; err != nil {
log.Error("apmSvc.ruleEdit delModule error(%v)", err)
c.JSON(nil, err)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "delete",
"Where": "DELETE FROM user_rule WHERE user_id=? AND rule IN (?)",
"Value1": usr.ID,
"Value2": ds,
"Update": "",
"Old": "",
}
username := name(c)
sqlLogs = append(sqlLogs, sqlLog)
for _, n := range ns {
if err = apmSvc.DB.Create(n).Error; err != nil {
log.Error("apmSvc.ruleEdit addModule error(%v)", err)
c.JSON(nil, err)
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.ruleEdit", sqlLogs)
return
}
sqlLog := &map[string]interface{}{
"SQLType": "add",
"Content": n,
}
sqlLogs = append(sqlLogs, sqlLog)
}
apmSvc.SendLog(*c, username, 0, 2, 0, "apmSvc.ruleEdit", sqlLogs)
c.JSON(nil, err)
}
func userSyncTree(c *bm.Context) {
username := name(c)
apmSvc.TreeSync(c, username, c.Request.Header.Get("Cookie"))
c.JSON(nil, nil)
}
func userTreeAppids(c *bm.Context) {
username := name(c)
appids, err := apmSvc.Appids(c, username, c.Request.Header.Get("Cookie"))
if err != nil {
log.Error("%v", err)
c.JSON(nil, err)
return
}
c.JSON(appids, nil)
}
func userTreeDiscovery(c *bm.Context) {
username := name(c)
appids, err := apmSvc.DiscoveryID(c, username, c.Request.Header.Get("Cookie"))
if err != nil {
log.Error("%v", err)
c.JSON(nil, err)
return
}
c.JSON(appids, nil)
}

View File

@@ -0,0 +1,87 @@
package http
import (
"context"
"encoding/json"
"flag"
"fmt"
"net/http"
"net/url"
"strings"
"testing"
"go-common/app/admin/main/apm/conf"
bm "go-common/library/net/http/blademaster"
. "github.com/smartystreets/goconvey/convey"
)
func TestUserRuleStates(t *testing.T) {
fmt.Println("========UserRuleStates tests========")
Convey("test userAuth", t, func() {
var params = url.Values{}
ctx := userRequest("GET", params)
userRuleStates(&ctx)
data, err := json.Marshal(ctx)
fmt.Println(string(data))
So(err, ShouldBeNil)
})
}
func TestUserApplies(t *testing.T) {
fmt.Println("========UserAppliestests========")
Convey("test userApplies", t, func() {
var params = url.Values{}
ctx := userRequest("GET", params)
userApplies(&ctx)
data, err := json.Marshal(ctx)
fmt.Println(string(data))
So(err, ShouldBeNil)
})
}
// func TestUserApply(t *testing.T) {
// fmt.Println("========UserApply tests========")
// Convey("test userApply", t, func() {
// var params = url.Values{}
// params.Set("item", "APP_AUTH_VIEW,APP_EDIT")
// ctx := userRequest("POST", params)
// userApply(&ctx)
// data, err := json.Marshal(ctx)
// fmt.Println(string(data))
// So(err, ShouldBeNil)
// })
// }
// func TestUserAudit(t *testing.T) {
// fmt.Println("========UserAudit tests========")
// Convey("test userAudit", t, func() {
// var params = url.Values{}
// params.Set("id", "2")
// params.Set("status", "2")
// ctx := userRequest("POST", params)
// userAudit(&ctx)
// data, err := json.Marshal(ctx)
// fmt.Println(string(data))
// So(err, ShouldBeNil)
// })
// }
func userRequest(method string, params url.Values) (ctx bm.Context) {
flag.Set("conf", "../cmd/apm-admin-test.toml")
conf.Init()
//apmSvc = service.New(conf.Conf)
path := "/"
req, _ := http.NewRequest(method, path, strings.NewReader(params.Encode()))
req.Header.Set("X-BACKEND-BILI-REAL-IP", "xxx")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Cookie", "_AJSESSIONID=0eac92f0621b11e8b877522233007f8a; username=chengxing; sven-apm=fa7128be35363eb623e4dd5d611daf1f3273316cc09a66655db0e79f616d4f53")
req.ParseForm()
ctx = bm.Context{
Context: context.TODO(),
Request: req,
}
ctx.Set("username", "chengxing")
ctx.Request.ParseForm()
return
}

View File

@@ -0,0 +1,140 @@
package http
import (
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/ut"
saga "go-common/app/tool/saga/model"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
// @params ListReq
// @router get /x/admin/apm/ut/info/list
// @response Paper
func utList(c *bm.Context) {
var (
mrInfs []*ut.Merge
data *Paper
err error
count int
)
v := new(ut.MergeReq)
if err = c.Bind(v); err != nil {
return
}
if mrInfs, count, err = apmSvc.UtList(c, v); err != nil {
c.JSON(nil, err)
return
}
data = &Paper{
Total: count,
Pn: v.Pn,
Ps: v.Ps,
Items: mrInfs,
}
c.JSON(data, nil)
}
// @params DetailReq
// @router get /x/admin/apm/ut/detail/list
// @response PkgAnls
func utDetail(c *bm.Context) {
var (
utpkgs []*ut.PkgAnls
err error
)
v := new(ut.DetailReq)
if err = c.Bind(v); err != nil {
return
}
if utpkgs, err = apmSvc.UtDetailList(c, v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(utpkgs, nil)
}
// @params HistoryCommitReq
// @router get /x/admin/apm/ut/history/commit
// @response Commit
func utHistoryCommit(c *bm.Context) {
var (
utcmts []*ut.Commit
count int
err error
data *Paper
)
v := new(ut.HistoryCommitReq)
if err = c.Bind(v); err != nil {
return
}
if utcmts, count, err = apmSvc.UtHistoryCommit(c, v); err != nil {
c.JSON(nil, err)
return
}
data = &Paper{
Total: count,
Pn: v.Pn,
Ps: v.Ps,
Items: utcmts,
}
c.JSON(data, nil)
}
func utBaseline(c *bm.Context) {
data := map[string]int{
"coverage": conf.Conf.UTBaseLine.Coverage,
"passrate": conf.Conf.UTBaseLine.Passrate,
}
c.JSON(data, nil)
}
// @params commit_id
// @router get /x/admin/apm/ut/check
// @response Tyrant
func check(c *bm.Context) {
var (
err error
ty *ut.Tyrant
res = new(struct {
CommitID string `form:"commit_id" validate:"required"`
})
)
if err = c.Bind(res); err != nil {
c.JSON(nil, err)
return
}
if ty, err = apmSvc.CheckUT(c, res.CommitID); err != nil {
c.JSON(nil, err)
return
}
c.JSON(ty, nil)
}
// @params merge_id
// @router get /x/admin/apm/ut/merge/set
// @response message
func utSetMerged(c *bm.Context) {
var (
err error
hookMR = &saga.HookMR{}
)
if err = c.BindWith(hookMR, binding.JSON); err != nil {
return
}
if hookMR.ObjectAttributes.State != "merged" {
c.JSON(nil, nil)
return
}
if err = apmSvc.SetMerged(c, hookMR.ObjectAttributes.IID); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.WechatReport(c, hookMR.ObjectAttributes.IID, hookMR.ObjectAttributes.LastCommit.ID, hookMR.ObjectAttributes.SourceBranch, hookMR.ObjectAttributes.TargetBranch); err != nil {
c.JSON(nil, err)
return
}
c.JSONMap(map[string]interface{}{
"message": "单元测试is_merged更新成功",
}, nil)
}

View File

@@ -0,0 +1,30 @@
package http
import (
"go-common/app/admin/main/apm/model/ut"
bm "go-common/library/net/http/blademaster"
)
// utApps
func utApps(c *bm.Context) {
var (
err error
count int
res = []*ut.App{}
)
v := new(ut.AppReq)
if err = c.Bind(v); err != nil {
return
}
if res, count, err = apmSvc.UTApps(c, v); err != nil {
c.JSON(nil, err)
return
}
data := &Paper{
Pn: v.Pn,
Ps: v.Ps,
Items: res,
Total: count,
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,185 @@
package http
import (
"go-common/app/admin/main/apm/conf"
"go-common/app/admin/main/apm/model/ut"
bm "go-common/library/net/http/blademaster"
)
// @params PCurveReq
// @router get /x/admin/apm/ut/dashboard/pcurve
// @response PCurveResp
func utDashCurve(c *bm.Context) {
var (
curve []*ut.PCurveResp
err error
)
v := new(ut.PCurveReq)
if err = c.Bind(v); err != nil {
return
}
if curve, err = apmSvc.DashCurveGraph(c, name(c), v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(curve, nil)
}
// @params PCurveReq
// @router get /x/admin/apm/ut/dashboard/histogram
// @response PCurveDetailResp
func utDashHistogram(c *bm.Context) {
var (
histogram []*ut.PCurveDetailResp
err error
)
v := new(ut.PCurveReq)
if err = c.Bind(v); err != nil {
return
}
if histogram, err = apmSvc.DashGraphDetail(c, name(c), v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(histogram, nil)
}
// @params PCurveReq
// @router get /x/admin/apm/ut/dashboard/user/detail
// @response PCurveDetailResp
func utDashUserDetail(c *bm.Context) {
var (
detail []*ut.PCurveDetailResp
err error
)
v := new(ut.PCurveReq)
if err = c.Bind(v); err != nil {
return
}
if detail, err = apmSvc.DashGraphDetailSingle(c, name(c), v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(detail, nil)
}
// @params QATrendReq
// @router get /x/admin/apm/ut/quality/trend
// @response QATrendResp
func utQATrend(c *bm.Context) {
var (
trend *ut.QATrendResp
err error
)
v := new(ut.QATrendReq)
if err = c.Bind(v); err != nil {
return
}
if trend, err = apmSvc.QATrend(c, v); err != nil {
c.JSON(nil, err)
return
}
c.JSON(trend, nil)
}
// @params commits
// @router get /x/admin/apm/ut/commits
// @response CommitInfo
func utGeneralCommit(c *bm.Context) {
var (
cmInfos []*ut.CommitInfo
err error
)
v := new(struct {
Commits string `form:"commits"`
})
if err = c.Bind(v); err != nil {
return
}
if cmInfos, err = apmSvc.UTGernalCommit(c, v.Commits); err != nil {
c.JSON(nil, err)
return
}
c.JSON(cmInfos, nil)
}
// @params pkg
// @router get /x/admin/apm/ut/dashboard/pkgs
// @response []*ut.PkgAnls
func utDashPkgsTree(c *bm.Context) {
var (
err error
pkgs []*ut.PkgAnls
username = name(c)
req = new(struct {
PKG string `form:"pkg"`
})
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if pkgs, err = apmSvc.DashPkgsTree(c, req.PKG, username); err != nil {
c.JSON(nil, err)
return
}
c.JSON(pkgs, nil)
}
// @params project_id,merge_id,commit_id
// @router get /x/admin/apm/ut/git/report
// @response EmptyResp
func utGitReport(c *bm.Context) {
var (
err error
req = new(struct {
ProjectID int `form:"project_id" validate:"required"`
MergeID int `form:"merge_id" validate:"required"`
CommitID string `form:"commit_id" validate:"required"`
})
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if err = apmSvc.GitReport(c, req.ProjectID, req.MergeID, req.CommitID); err != nil {
c.JSON(nil, err)
return
}
}
// @params username,times
// @router get /x/admin/apm/ut/dashboard/history/commit
// @response []*ut.PkgAnls
func dashHistoryCommit(c *bm.Context) {
var (
err error
pkgs = make([]*ut.PkgAnls, 0)
req = new(struct {
UserName string `form:"user_name" default:""`
Times int64 `form:"times" default:"10"`
})
)
if err = c.Bind(req); err != nil {
c.JSON(nil, err)
return
}
if req.UserName == "" {
req.UserName = name(c)
}
if pkgs, err = apmSvc.CommitHistory(c, req.UserName, req.Times); err != nil {
c.JSON(nil, err)
return
}
data := new(struct {
Pkgs []*ut.PkgAnls `json:"pkgs"`
BaseLine struct {
Coverage int `json:"coverage"`
PassRate int `json:"pass_rate"`
} `json:"base_line"`
})
data.Pkgs = pkgs
data.BaseLine.Coverage = conf.Conf.UTBaseLine.Coverage
data.BaseLine.PassRate = conf.Conf.UTBaseLine.Passrate
c.JSON(data, nil)
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/apm/model/app:all-srcs",
"//app/admin/main/apm/model/canal:all-srcs",
"//app/admin/main/apm/model/databus:all-srcs",
"//app/admin/main/apm/model/discovery:all-srcs",
"//app/admin/main/apm/model/ecode:all-srcs",
"//app/admin/main/apm/model/log:all-srcs",
"//app/admin/main/apm/model/monitor:all-srcs",
"//app/admin/main/apm/model/need:all-srcs",
"//app/admin/main/apm/model/pprof:all-srcs",
"//app/admin/main/apm/model/tree:all-srcs",
"//app/admin/main/apm/model/user:all-srcs",
"//app/admin/main/apm/model/ut:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"auth.go",
],
importpath = "go-common/app/admin/main/apm/model/app",
tags = ["automanaged"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,20 @@
package app
import (
xtime "go-common/library/time"
)
// TableName case tablename
func (*App) TableName() string {
return "app"
}
// App app
type App struct {
ID int64 `gorm:"column:id" json:"id"`
AppTreeID int64 `gorm:"column:app_tree_id" json:"app_tree_id"`
AppID string `gorm:"column:app_id" json:"app_id"`
Limit int64 `gorm:"column:limit" json:"limit"`
CTime xtime.Time `gorm:"column:ctime" json:"ctime"`
MTime xtime.Time `gorm:"column:mtime" json:"mtime"`
}

View File

@@ -0,0 +1,24 @@
package app
import (
xtime "go-common/library/time"
)
// TableName case tablename
func (*Auth) TableName() string {
return "app_auth"
}
// Auth app auth
type Auth struct {
ID int64 `gorm:"column:id" json:"id"`
ServiceTreeID int64 `gorm:"column:service_tree_id" json:"service_tree_id"`
AppTreeID int64 `gorm:"column:app_tree_id" json:"app_tree_id"`
ServiceID string `gorm:"column:service_id" json:"service_id"`
AppID string `gorm:"column:app_id" json:"app_id"`
RPCMethod string `gorm:"column:rpc_method" json:"rpc_method"`
HTTPMethod string `gorm:"column:http_method" json:"http_method"`
Quota int64 `gorm:"column:quota" json:"quota"`
CTime xtime.Time `gorm:"column:ctime" json:"ctime"`
MTime xtime.Time `gorm:"column:mtime" json:"mtime"`
}

View File

@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"apply.go",
"canal.go",
],
importpath = "go-common/app/admin/main/apm/model/canal",
tags = ["automanaged"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,116 @@
package canal
import (
"go-common/library/time"
)
//type and explanation
const (
TypeApply = int8(iota)
TypeReview
ReviewReject
ReviewSuccess
ReviewFailed
)
//TypeMap struct
var (
TypeMap = map[int8]string{
TypeApply: "申请",
TypeReview: "审核",
ReviewReject: "驳回",
ReviewSuccess: "通过",
ReviewFailed: "失败",
}
)
// TableName case tablename
func (*Apply) TableName() string {
return "canal_apply"
}
//Apply apply model
type Apply struct {
ID int `gorm:"column:id" json:"id"`
Addr string `gorm:"column:addr" json:"addr"`
Remark string `gorm:"column:remark" json:"remark"`
Cluster string `gorm:"column:cluster" json:"project"`
Leader string `gorm:"column:leader" json:"leader"`
Comment string `gorm:"column:comment" json:"comment"`
State int8 `gorm:"column:state" json:"status"`
Operator string `gorm:"column:operator" json:"operator"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
ConfID int `gorm:"column:conf_id" json:"conf_id"`
}
//Config struct
type Config struct {
Instance *Instance `json:"instance" toml:"instance"`
}
//Instance struct
type Instance struct {
Caddr string `json:"caddr" toml:"addr"`
User string `json:"user" toml:"user"`
Password string `json:"password" toml:"password"`
MonitorPeriod string `json:"monitor_period" toml:"monitor_period,omitempty"`
ServerID int64 `json:"server_id" toml:"server_id"`
Flavor string `json:"flavor" toml:"flavor"`
HeartbeatPeriod time.Duration `json:"heartbeat_period" toml:"heartbeat_period"`
ReadTimeout time.Duration `json:"read_timeout" toml:"read_timeout"`
DB []*DB `json:"db" toml:"db"`
}
//DB struct
type DB struct {
Schema string `json:"schema" toml:"schema"`
Table []*Table `json:"table" toml:"table"`
Databus *Databus `json:"databus" toml:"databus"`
Infoc *Infoc `json:"infoc" toml:"infoc"`
}
//Table struct
type Table struct {
Name string `json:"name" toml:"name"`
Primarykey []string `json:"primarykey" toml:"primarykey"`
Omitfield []string `json:"omitfield" toml:"omitfield"`
}
//Databus struct
type Databus struct {
Key string `json:"key" toml:"key"`
Secret string `json:"secret" toml:"secret"`
Group string `json:"group" toml:"group"`
Topic string `json:"topic" toml:"topic"`
Action string `json:"action" toml:"action"`
Name string `json:"name" toml:"name"`
Proto string `json:"proto" toml:"proto"`
Addr string `json:"addr" toml:"addr"`
Idle int `json:"idle" toml:"idle"`
Active int `json:"active" toml:"active"`
DialTimeout string `json:"dialTimeout" toml:"dialTimeout"`
ReadTimeout string `json:"readTimeout" toml:"readTimeout"`
WriteTimeout string `json:"writeTimeout" toml:"writeTimeout"`
IdleTimeout string `json:"idleTimeout" toml:"idleTimeout"`
}
//Infoc struct
type Infoc struct {
TaskID string `json:"taskID" toml:"taskID"`
Proto string `json:"proto" toml:"proto"`
Addr string `json:"addr" toml:"addr"`
ReporterAddr string `json:"reporterAddr" toml:"reporterAddr"`
}
//ConfigReq struct is
type ConfigReq struct {
Addr string `form:"addr" validate:"required"`
User string `form:"user"`
Password string `form:"password"`
MonitorPeriod string `form:"monitor_period"`
Databases string `form:"databases" validate:"required"`
Project string `form:"project"`
Leader string `form:"leader"`
Mark string `form:"mark" validate:"required"`
}

View File

@@ -0,0 +1,109 @@
package canal
import (
xtime "go-common/library/time"
)
// TableName case tablename
func (*Canal) TableName() string {
return "master_info"
}
// Canal canal
type Canal struct {
ID int64 `gorm:"column:id" json:"id"`
Addr string `gorm:"column:addr" json:"addr" form:"addr" validate:"required"`
BinName string `gorm:"column:bin_name" json:"bin_name" form:"bin_name"`
BinPos int32 `gorm:"column:bin_pos" json:"bin_pos" form:"bin_pos"`
Remark string `gorm:"column:remark" json:"remark" form:"remark"`
Leader string `gorm:"column:leader" json:"leader" form:"leader"`
Cluster string `gorm:"column:cluster" json:"project" form:"project"`
CTime xtime.Time `gorm:"column:ctime" json:"ctime"`
MTime xtime.Time `gorm:"column:mtime" json:"mtime"`
IsDelete int `gorm:"column:is_delete" json:"is_delete"`
}
//ScanReq canal scan req
type ScanReq struct {
Addr string `form:"addr" validate:"required"`
}
//Results canalscan resp
type Results struct {
ID int64 `json:"id"`
Addr string `json:"addr"`
Cluster string `json:"project"`
Leader string `json:"leader"`
Document *Document `json:"document"`
}
//EditReq canal edit req
type EditReq struct {
ID int64 `form:"id" validate:"required"`
BinName string `form:"bin_name"`
BinPos int32 `form:"bin_pos"`
Remark string `form:"remark"`
Leader string `form:"leader"`
Project string `form:"project"`
}
//ListReq canallist req
type ListReq struct {
Addr string `form:"addr"`
Project string `form:"project"`
Status int8 `form:"status"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
}
//Paper canallist resp
type Paper struct {
Total int `json:"total"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items interface{} `json:"items"`
}
//Conf is
type Conf struct {
ID int64 `json:"id"`
Comment string `json:"comment"`
}
//Document document
type Document struct {
Instance struct {
User string `json:"user" toml:"user"`
Password string `json:"password" toml:"password"`
MonitorPeriod string `json:"monitor_period" toml:"monitor_period"`
ServerID int64 `json:"server_id" toml:"server_id"`
Db []*struct {
Schema string `json:"schema" toml:"schema"`
Table []*struct {
Name string `json:"name" toml:"name"`
Primarykey []string `json:"primarykey,omitempty" toml:"primarykey"`
Omitfield []string `json:"omitfield,omitempty" toml:"omitfield"`
} `json:"table" toml:"table"`
Databus *struct {
Group string `json:"group" toml:"group"`
Topic string `json:"topic" toml:"topic"`
Action string `json:"action" toml:"action"`
Name string `json:"name" toml:"name"`
Proto string `json:"proto" toml:"proto"`
Addr string `json:"addr" toml:"addr"`
Idle int `json:"idle" toml:"idle"`
Active int `json:"active" toml:"active"`
DialTimeout string `json:"dialTimeout" toml:"dialTimeout"`
ReadTimeout string `json:"readTimeout" toml:"readTimeout"`
WriteTimeout string `json:"writeTimeout" toml:"writeTimeout"`
IdleTimeout string `json:"idleTimeout" toml:"idleTimeout"`
} `json:"databus" toml:"databus"`
Infoc *struct {
TaskID string `json:"taskID" toml:"taskID"`
Proto string `json:"proto" toml:"proto"`
Addr string `json:"addr" toml:"addr"`
ReporterAddr string `json:"reporterAddr" toml:"reporterAddr"`
} `json:"infoc" toml:"infoc"`
} `json:"db"`
} `json:"instance"`
}

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"alarm.go",
"app.go",
"apply.go",
"auth.go",
"filter.go",
"message.go",
"notify.go",
"notifygroup.go",
"oldapp.go",
"oldauth.go",
"topic.go",
],
importpath = "go-common/app/admin/main/apm/model/databus",
tags = ["automanaged"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,96 @@
package databus
// AlarmOpen ...
type AlarmOpen struct {
ReqID string `json:"ReqId"`
Action string `json:"Action"`
RetCode int64 `json:"RetCode"`
Data []*Open `json:"Data"`
}
// Open ...
type Open struct {
AdjustID string `json:"adjust_id"`
PolicyID string `json:"policy_id"`
Group string `json:"group"`
}
//Scope ...
type Scope struct {
Type int64
Key string
Val []string
}
//Owner ...
type Owner struct {
Owner string `json:"owner"`
App string `json:"app"`
}
// Res ...
type Res struct {
ReqID string `json:"ReqId"`
Action string `json:"Action"`
RetCode int64 `json:"RetCode"`
Data Opsmind `json:"Data"`
}
// Opsmind ...
type Opsmind struct {
PolicyID string `json:"policy_id"`
AdjustID string `json:"adjust_id"`
Category string `json:"category"`
Scope string `json:"scope"`
TriggerID string `json:"trigger_id"`
TriggerLevel string `json:"trigger_level"`
TriggerFor int64 `json:"trigger_for"`
TriggerNotes string `json:"trigger_notes"`
TriggerOperator string `json:"trigger_operator"`
TriggerThreshold int64 `json:"trigger_threshold"`
Silence bool `json:"silence"`
Hashid string `json:"hashid"`
ExpiredAt string `json:"expired_at"`
}
//Query ...
type Query struct {
Key string
Val []string
}
// ResQuery ...
type ResQuery struct {
ReqID string `json:"ReqId"`
Action string `json:"Action"`
RetCode int64 `json:"RetCode"`
Data []*Querys `json:"Data"`
}
// Querys ...
type Querys struct {
ID string `json:"id"`
PolicyID string `json:"policy_id"`
Creator string `json:"creator"`
Ctime int64 `json:"ctime"`
Mtime int64 `json:"mtime"`
Scope []*Scope `json:"scope"`
Triggers []*Trigger `json:"triggers"`
Notes *Owner `json:"notes"`
Desc string `json:"desc"`
Silence bool `json:"silence"`
ExpiredAt int64 `json:"expired_at"`
}
//Trigger ...
type Trigger struct {
ID string `json:"id"`
Desc string `json:"desc"`
Operator string `json:"operator"`
For int64 `json:"for"`
Threshold float64 `json:"threshold"`
Level string `json:"level"`
NodataType string `json:"nodata_type"`
NodataFor int64 `json:"nodata_for"`
Notes *Owner `json:"notes"`
}

View File

@@ -0,0 +1,19 @@
package databus
import "go-common/library/time"
// TableName case tablename
func (*App) TableName() string {
return "app2"
}
// App app model
type App struct {
ID int `gorm:"column:id" json:"id"`
AppKey string `gorm:"column:app_key" json:"app_key"`
AppSecret string `gorm:"column:app_secret" json:"app_secret"`
Project string `gorm:"column:project" json:"cluster"`
Remark string `gorm:"column:remark" json:"remark"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}

View File

@@ -0,0 +1,37 @@
package databus
import "go-common/library/time"
// TableName case tablename
func (*Apply) TableName() string {
return "group_apply"
}
// Apply apply model
type Apply struct {
ID int `gorm:"column:id" json:"id"`
Group string `gorm:"column:group" json:"group"`
Cluster string `gorm:"column:cluster" json:"cluster"`
TopicRemark string `gorm:"column:topic_remark" json:"topic_remark"`
TopicID int `gorm:"column:topic_id" json:"topic_id"`
TopicName string `gorm:"column:topic_name" json:"topic"`
AppID int `gorm:"column:app_id" json:"app_id"`
Project string `gorm:"column:project" json:"project"`
Operation int8 `gorm:"column:operation" json:"operation"`
State int8 `gorm:"column:state" json:"state"`
Operator string `gorm:"column:operator" json:"operator"`
Remark string `gorm:"column:remark" json:"remark"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
// notify
Gid int `gorm:"-" json:"notify_gid"`
Nid int64 `gorm:"-" json:"notify_id"`
Offset string `gorm:"-" json:"notify_offset"`
Nstate int8 `gorm:"-" json:"notify_state"`
Filter int8 `gorm:"-" json:"notify_filter"`
Concurrent int8 `gorm:"-" json:"notify_concurrent"`
Callback string `gorm:"-" json:"notify_callback"`
Filters string `gorm:"-" json:"-"`
FilterList []*Filter `gorm:"-" json:"filters"`
Zone string `gorm:"-" json:"notify_zone"`
}

View File

@@ -0,0 +1,65 @@
package databus
import (
"go-common/library/time"
)
// TableName case tablename
func (*Group) TableName() string {
return "auth2"
}
// Group group model
type Group struct {
ID int `gorm:"column:id" json:"id"`
Group string `gorm:"column:group" json:"group"`
AppID int `gorm:"column:app_id" json:"app_id"`
AppKey string `gorm:"-" json:"app_key"`
Project string `gorm:"-" json:"project"`
TopicID int `gorm:"column:topic_id" json:"topic_id"`
Topic string `gorm:"-" json:"topic"`
Cluster string `gorm:"-" json:"cluster"`
Operation int8 `gorm:"column:operation" json:"operation"`
IsDelete int8 `gorm:"column:is_delete" json:"is_delete"`
Remark string `gorm:"column:remark" json:"remark"`
Alarm int8 `gorm:"column:alarm;default:1" json:"alarm"`
Percentage string `gorm:"column:percentage" json:"percentage"`
Number int `gorm:"column:number" json:"number"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
Callback string `gorm:"-" json:"notify_callback"`
Concurrent string `gorm:"-" json:"notify_concurrent"`
Filter int8 `gorm:"-" json:"notify_filter"`
Filters string `gorm:"-" json:"-"`
FilterList []*Filter `gorm:"-" json:"filters"`
State int8 `gorm:"-" json:"notify_state"`
Gid int64 `gorm:"-" json:"notify_gid"`
Nid int64 `gorm:"-" json:"notify_id"`
Zone string `gorm:"-" json:"notify_zone"`
}
//Alarm alarm
type Alarm struct {
Group string `json:"group"`
Project string `json:"project"`
Alarm int8 `json:"alarm"`
Percentage string `json:"percentage"`
}
//Alarms alarms
type Alarms struct {
Cluster string `json:"cluster"`
Topic string `json:"topic"`
Group string `json:"group"`
Project string `json:"project"`
Alarm int8 `json:"alarm"`
Percentage string `json:"percentage"`
Diff []*Record `json:"diff"`
}
// Record diff
type Record struct {
Partition int32 `json:"partition"`
Diff int64 `json:"diff"`
New int64 `json:"new"`
}

View File

@@ -0,0 +1,16 @@
package databus
// TableName case tablename
func (*Filter) TableName() string {
return "filters"
}
// Filter apply model
type Filter struct {
ID int `gorm:"column:id" json:"id"`
Nid int `gorm:"column:nid" json:"nid"`
Filters string `gorm:"column:filters" json:"-"`
Field string `gorm:"-" json:"field"`
Condition int8 `gorm:"-" json:"condition"`
Value string `gorm:"-" json:"value"`
}

View File

@@ -0,0 +1,11 @@
package databus
// Message Data.
type Message struct {
Key string `json:"key"`
Value string `json:"value"`
Topic string `json:"topic"`
Partition int32 `json:"partition"`
Offset int64 `json:"offset"`
Timestamp int64 `json:"timestamp"`
}

View File

@@ -0,0 +1,22 @@
package databus
import "go-common/library/time"
// TableName case tablename
func (*Notify) TableName() string {
return "notify"
}
// Notify apply model
type Notify struct {
ID int `gorm:"column:id" json:"id"`
Gid int `gorm:"column:gid" json:"gid"`
Offset string `gorm:"column:offset" json:"offset"`
State int8 `gorm:"column:state" json:"state"`
Filter int8 `gorm:"column:filter" json:"filter"`
Concurrent int8 `gorm:"column:concurrent" json:"concurrent"`
Callback string `gorm:"column:callback" json:"callback"`
Zone string `gorm:"column:zone" json:"zone"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
}

View File

@@ -0,0 +1,34 @@
package databus
import "go-common/library/time"
// TableName case tablename
func (*NotifyGroup) TableName() string {
return "group_apply"
}
// NotifyGroup apply model
type NotifyGroup struct {
ID int `gorm:"column:id" json:"notify_id"`
Gid int `gorm:"column:gid" json:"notify_gid"`
Offset string `gorm:"column:offset" json:"notify_offset"`
State int8 `gorm:"column:state" json:"notify_state"`
Filter int8 `gorm:"column:filter" json:"notify_filter"`
Concurrent int8 `gorm:"column:concurrent" json:"notify_concurrent"`
Callback string `gorm:"column:callback" json:"notify_callback"`
Ctime time.Time `gorm:"column:ctime" json:"notify_ctime"`
Mtime time.Time `gorm:"column:mtime" json:"notify_mtime"`
GGroup string `gorm:"column:group" json:"group"`
GCluster string `gorm:"column:cluster" json:"cluster"`
GTopicRemark string `gorm:"column:topic_remark" json:"topic_remark"`
GTopicID int `gorm:"column:topic_id" json:"topic_id"`
GTopicName string `gorm:"column:topic_name" json:"topic"`
GAppID int `gorm:"column:app_id" json:"app_id"`
GState int8 `gorm:"column:gstate" json:"state"`
GOperation int8 `gorm:"column:operation" json:"operation"`
GOperator string `gorm:"column:operator" json:"operator"`
GRemark string `gorm:"column:remark" json:"remark"`
Filters string `gorm:"column:filters" json:"filters"`
GCtime time.Time `gorm:"column:gctime" json:"ctime"`
GMtime time.Time `gorm:"column:gmtime" json:"mtime"`
}

View File

@@ -0,0 +1,18 @@
package databus
import "go-common/library/time"
// TableName case tablename
func (*OldApp) TableName() string {
return "app"
}
// OldApp app model
type OldApp struct {
ID int64 `gorm:"column:id" json:"id"`
AppKey string `gorm:"column:app_key" json:"app_key"`
AppSecret string `gorm:"column:app_secret" json:"app_secret"`
Cluster string `gorm:"column:cluster" json:"cluster"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}

View File

@@ -0,0 +1,22 @@
package databus
import (
"go-common/library/time"
)
// TableName case tablename
func (*OldAuth) TableName() string {
return "auth"
}
// OldAuth group model
type OldAuth struct {
ID int64 `gorm:"column:id" json:"id"`
GroupName string `gorm:"column:group_name" json:"group_name"`
Topic string `gorm:"column:topic" json:"topic"`
Business string `gorm:"business" json:"business"`
AppID int64 `gorm:"column:app_id" json:"app_id"`
Operation int8 `gorm:"column:operation" json:"operation"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
}

View File

@@ -0,0 +1,20 @@
package databus
import (
"go-common/library/time"
)
// TableName case tablename
func (*Topic) TableName() string {
return "topic"
}
// Topic topic
type Topic struct {
ID int `gorm:"column:id" json:"id"`
Topic string `gorm:"column:topic" json:"topic"`
Cluster string `gorm:"column:cluster" json:"cluster"`
Remark string `gorm:"column:remark" json:"remark"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}

View File

@@ -0,0 +1,27 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["discovery.go"],
importpath = "go-common/app/admin/main/apm/model/discovery",
tags = ["automanaged"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,13 @@
package discovery
// Status node
type Status struct {
Status int `json:"status"`
Others interface{} `json:"others"`
}
// Addr addr
type Addr struct {
Addr string `json:"addr"`
Status int `json:"status"`
}

View File

@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"code_msg.go",
"ecode.go",
],
importpath = "go-common/app/admin/main/apm/model/ecode",
tags = ["automanaged"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,21 @@
package codes
import (
xtime "go-common/library/time"
)
// TableName case tablename
func (*CodeMsg) TableName() string {
return "code_msg"
}
// CodeMsg ...
type CodeMsg struct {
ID int64 `gorm:"column:id" json:"cid"`
CodeID int64 `gorm:"column:code_id" json:"code_id"`
Locale string `gorm:"column:locale" json:"locale"`
Msg string `gorm:"column:msg" json:"msg"`
Operator string `gorm:"column:operator" json:"c_operator"`
CTime xtime.Time `gorm:"column:ctime" json:"c_ctime"`
MTime xtime.Time `gorm:"column:mtime" json:"c_mtime"`
}

View File

@@ -0,0 +1,41 @@
package codes
import (
xtime "go-common/library/time"
)
// code status
const (
StatusOpen = int8(1)
Type = int8(1)
)
// TableName case tablename
func (*Codes) TableName() string {
return "codes"
}
// Codes codes
type Codes struct {
ID int64 `gorm:"column:id" json:"id"`
Code int32 `gorm:"column:code" json:"code"`
Message string `gorm:"column:message" json:"message"`
Operator string `gorm:"column:operator" json:"operator"`
CTime xtime.Time `gorm:"column:ctime" json:"ctime"`
MTime xtime.Time `gorm:"column:mtime" json:"mtime"`
HantMessage string `gorm:"column:hant_message" json:"hant_message"`
Level int8 `gorm:"column:level" json:"level"`
}
// ResultCodes ...
type ResultCodes struct {
Code int32 `json:"code"`
Message string `json:"message"`
Data []*Codes
}
// NewCodes ...
type NewCodes struct {
*Codes
List []*CodeMsg `json:"list"`
}

View File

@@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["log.go"],
importpath = "go-common/app/admin/main/apm/model/log",
tags = ["automanaged"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,20 @@
package log
import (
xtime "go-common/library/time"
)
// TableName case tablename
func (*Log) TableName() string {
return "log"
}
// Log log model
type Log struct {
ID int64 `gorm:"column:id" json:"id"`
UserName string `gorm:"column:username" json:"username"`
Business string `gorm:"column:business" json:"business"`
Info string `gorm:"column:info" json:"info"`
CTime xtime.Time `gorm:"column:ctime" json:"ctime"`
MTime xtime.Time `gorm:"column:mtime" json:"mtime"`
}

View File

@@ -0,0 +1,29 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["monitor.go"],
importpath = "go-common/app/admin/main/apm/model/monitor",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,42 @@
package monitor
import (
"go-common/library/time"
)
// TableName define table name
func (*Monitor) TableName() string {
return "monitor"
}
// Monitor .
type Monitor struct {
ID int64 `gorm:"column:id" json:"id"`
AppID string `gorm:"column:app_id" json:"app_id"`
Interface string `gorm:"column:interface" json:"interface"`
Count int64 `gorm:"column:count" json:"count"`
Cost int64 `gorm:"column:cost" json:"cost"`
CTime time.Time `gorm:"column:ctime" json:"ctime"`
MTime time.Time `gorm:"column:mtime" json:"mtime"`
TempName string `gorm:"-" json:"temp_name"`
}
// Data .
type Data struct {
Interface string `json:"interface"`
Counts []int64 `json:"counts"`
Costs []int64 `json:"costs"`
Times []string `json:"times"`
}
// MoniRet .
type MoniRet struct {
XAxis []string `json:"xAxis"`
Items []*Items `json:"items"`
}
// Items .
type Items struct {
Interface string `json:"interface"`
YAxis []int64 `json:"yAxis"`
}

View File

@@ -0,0 +1,29 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["need.go"],
importpath = "go-common/app/admin/main/apm/model/need",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,111 @@
package need
import "go-common/library/time"
// type and states
const (
TypeCancel = 0
TypeLike = 1
TypeDislike = 2
VerifyAccept = 2
VerifyReject = 3
VerifyObserved = 4
NeedApply = 5
NeedVerify = 6
NeedReview = 7
)
//VerifyType is
var (
VerifyType = map[int]string{
VerifyAccept: "采纳",
VerifyReject: "驳回",
VerifyObserved: "待观察",
NeedApply: "申请",
NeedVerify: "确认",
NeedReview: "审核",
}
)
//TableName needs
func (*NInfo) TableName() string {
return "needs"
}
//NInfo struct
type NInfo struct {
ID int64 `gorm:"column:id" json:"id"`
Title string `gorm:"column:title" json:"title"`
Content string `gorm:"column:content" json:"content"`
Reporter string `gorm:"column:reporter" json:"reporter"`
Status int8 `gorm:"column:status" json:"status"`
LikeCounts int `gorm:"column:like_counts" json:"like_counts"`
DislikeCounts int `gorm:"column:dislike_counts" json:"dislike_counts"`
CTime time.Time `gorm:"column:ctime" json:"ctime"`
MTime time.Time `gorm:"column:mtime" json:"mtime"`
LikeState int8 `gorm:"-" json:"like_state"`
}
//NAddReq add request struct
type NAddReq struct {
Title string `form:"title" validate:"required"`
Content string `form:"content" validate:"required"`
}
// EmpResp is empty resp.
type EmpResp struct {
}
//NEditReq edit request struct
type NEditReq struct {
ID int64 `form:"id" validate:"required"`
Title string `form:"title"`
Content string `form:"content"`
}
//NListReq is list request struct
type NListReq struct {
Ps int `form:"ps" default:"20"`
Pn int `form:"pn" default:"1"`
Status int `form:"status"`
Reporter string `form:"reporter"`
}
//NListResp is list resp struct
type NListResp struct {
Data []*NInfo `json:"data"`
Total int64 `json:"total"`
}
//NVerifyReq is verify req struct
type NVerifyReq struct {
ID int64 `form:"id" validate:"required"`
Status int `form:"status" validate:"required"`
}
//TableName user_likes
func (*UserLikes) TableName() string {
return "user_likes"
}
//UserLikes struct
type UserLikes struct {
ID int64 `gorm:"column:id" json:"id"`
ReqID int64 `gorm:"column:req_id" json:"req_id"`
User string `gorm:"column:user" json:"user"`
LikeType int8 `gorm:"column:like_type" json:"like_type"`
CTime time.Time `gorm:"column:ctime" json:"ctime"`
MTime time.Time `gorm:"column:mtime" json:"mtime"`
}
//Likereq is userlike req struct
type Likereq struct {
ReqID int64 `form:"req_id" validate:"required"`
LikeType int8 `form:"like_type"`
}
//VoteListResp is vote resp struct
type VoteListResp struct {
Data []*UserLikes `json:"data"`
Total int64 `json:"total"`
}

View File

@@ -0,0 +1,29 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["pprof.go"],
importpath = "go-common/app/admin/main/apm/model/pprof",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,55 @@
package pprof
import (
"go-common/library/time"
)
// TableName .
func (*Warn) TableName() string {
return "pprof_warn"
}
// Warn .
type Warn struct {
ID int64 `gorm:"column:id" json:"id"`
AppID string `gorm:"column:app_id" json:"app_id"`
SvgName string `gorm:"column:svg_name" json:"svg_name"`
IP string `gorm:"column:ip" json:"ip"`
Kind int64 `gorm:"column:kind" json:"kind"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
URL string `gorm:"-" json:"url"`
}
// Response .
type Response struct {
Code int `json:"code"`
Data *Ins `json:"data"`
}
// Warning .
type Warning struct {
Tags struct {
App string `json:"app"`
} `json:"tags"`
}
// Ins .
type Ins struct {
Instances []struct {
Treeid int `json:"treeid"`
Hostname string `json:"hostname"`
Addrs []string `json:"addrs"`
Status int `json:"status"`
} `json:"instances"`
}
// Params .
type Params struct {
AppID string `form:"app_id" default:""`
SvgName string `form:"svg_name" default:""`
Kind int64 `form:"kind" default:"0"`
IP string `form:"ip" default:""`
StartTime time.Time `form:"start_time" default:"0"`
EndTime time.Time `form:"end_time" default:"0"`
}

View File

@@ -0,0 +1,27 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["tree.go"],
importpath = "go-common/app/admin/main/apm/model/tree",
tags = ["automanaged"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,65 @@
package tree
import "time"
// Token token
type Token struct {
Token string `json:"token"`
UserName string `json:"user_name"`
Secret string `json:"secret"`
Expired int64 `json:"expired"`
}
// TokenResult token result
type TokenResult struct {
Code int `json:"code"`
Data *Token `json:"data"`
Message string `json:"message"`
Status int `json:"status"`
}
// Resp tree resp
type Resp struct {
Data []*Node `json:"data"`
}
// Node node
type Node struct {
TreeID int `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
Type int `json:"type"`
Role int `json:"role"`
DiscoveryID string `json:"discovery_id"`
}
// Tree tree model
type Tree struct {
Project string `json:"project"`
Subs []*Tree `json:"subs"`
}
// Rest tree rest
type Rest struct {
Data []*Info `json:"data"`
}
// Info tree info
type Info struct {
AppTreeID int `json:"app_tree_id"`
AppID string `json:"app_id"`
}
// Resd tree resd
type Resd struct {
Data []*DiscoveryID `json:"data"`
CTime time.Time `json:"ctime"`
}
// DiscoveryID node
type DiscoveryID struct {
TreeID int `json:"app_tree_id"`
AppID string `json:"app_id"`
AppAuth string `json:"app_auth"`
DiscoveryID string `json:"discovery_id"`
}

View File

@@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"module.go",
"rule.go",
"user.go",
],
importpath = "go-common/app/admin/main/apm/model/user",
tags = ["automanaged"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,75 @@
package user
import (
"go-common/library/time"
)
// modules
const (
USER = "USER"
ECODE = "ECODE"
DATABUS = "DATABUS"
DAPPER = "DAPPER"
CONFIG = "CONFIG"
CANAL = "CANAL"
DISCOVERY = "DISCOVERY"
APP = "APP"
PLATFORM = "PLATFORM"
CACHE = "CACHE"
OPEN = "OPEN"
NEED = "NEED"
PERFORMANCE = "PERFORMANCE"
BFS = "BFS"
)
// Modules modules
var (
Modules = map[string]*Permission{
USER: {Name: "USER", Permit: PermitSuper, Des: "用户管理"},
ECODE: {Name: "ECODE", Permit: PermitDefault, Des: "错误码管理"},
DATABUS: {Name: "DATABUS", Permit: PermitDefault, Des: "DATABUS管理"},
DAPPER: {Name: "DAPPER", Permit: PermitDefault, Des: "DAPPER查询"},
CONFIG: {Name: "CONFIG", Permit: PermitDefault, Des: "配置中心"},
CANAL: {Name: "CANAL", Permit: PermitDefault, Des: "CANAL管理"},
DISCOVERY: {Name: "DISCOVERY", Permit: PermitDefault, Des: "DISCOVERY管理"},
APP: {Name: "APP", Permit: PermitDefault, Des: "APP管理"},
PLATFORM: {Name: "PLATFORM", Permit: PermitAuth, Des: "平台管理"},
CACHE: {Name: "CACHE", Permit: PermitDefault, Des: "缓存集群"},
OPEN: {Name: "OPEN", Permit: PermitDefault, Des: "open鉴权管理"},
NEED: {Name: "NEED", Permit: PermitDefault, Des: "需求管理"},
PERFORMANCE: {Name: "PERFORMANCE", Permit: PermitDefault, Des: "性能管理"},
BFS: {Name: "BFS", Permit: PermitAuth, Des: "BFS管理"},
}
)
// var (
// Modules = map[string]string{
// USER: "用户管理",
// ECODE: "错误码管理",
// DATABUS: "DATABUS管理",
// DAPPER: "DAPPER查询",
// CONFIG: "配置中心",
// CANAL: "CANAL管理",
// DISCOVERY: "DISCOVERY管理",
// APP: "APP管理",
// PLATFORM: "平台管理",
// CACHE: "缓存集群",
// OPEN: "open鉴权管理",
// NEED: "需求管理",
// }
// DefaultModules = []string{ECODE, DATABUS, DAPPER, CONFIG, CANAL, DISCOVERY, APP, CACHE, OPEN}
// )
// TableName case tablename
func (*Module) TableName() string {
return "user_module"
}
// Module module model
type Module struct {
ID int64 `gorm:"column:id" json:"id"`
UserID int64 `gorm:"column:user_id" json:"user_id"`
Module string `gorm:"column:module" json:"module"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}

View File

@@ -0,0 +1,151 @@
package user
import (
"go-common/library/time"
)
// rules
const (
UserView = "USER_VIEW"
UserEdit = "USER_EDIT"
UserAudit = "USER_AUDIT"
EcodeView = "ECODE_VIEW"
EcodeEdit = "ECODE_EDIT"
DatabusKeyView = "DATABUS_KEY_VIEW"
DatabusKeyEdit = "DATABUS_KEY_EDIT"
DatabusGroupView = "DATABUS_GROUP_VIEW"
DatabusGroupEdit = "DATABUS_GROUP_EDIT"
DatabusTopicView = "DATABUS_TOPIC_VIEW"
DatabusTopicEdit = "DATABUS_TOPIC_EDIT"
DatabusNotifyView = "DATABUS_NOTIFY_VIEW"
DatabusNotifyEdit = "DATABUS_NOTIFY_EDIT"
DatabusGroupApply = "DATABUS_GROUP_APPLY"
DapperView = "DAPPER_VIEW"
CanalView = "CANAL_VIEW"
CanalEdit = "CANAL_EDIT"
ConfigView = "CONFIG_VIEW"
ConfigSearchView = "CONFIG_SEARCH_VIEW"
ConfigPublicView = "CONFIG_PUBLIC_VIEW"
DiscoveryView = "DISCOVERY_VIEW"
PerformanceManager = "PERFORMANCE_MANAGER"
AppView = "APP_VIEW"
AppEdit = "APP_EDIT"
AppAuthView = "APP_AUTH_VIEW"
AppCallerSearch = "APP_CALLER_SEARCH"
NeedVerify = "NEED_VERIFY"
PlatformSearchView = "PLATFORM_SEARCH_VIEW"
PlatformReplyView = "PLATFORM_REPLY_VIEW"
PlatformTagView = "PLATFORM_TAG_VIEW"
CacheOpsView = "CACHE_OPS_VIEW"
OpenView = "OPEN_VIEW"
BFSView = "BFS_VIEW"
BFSEdit = "BFS_EDIT"
)
//PermitType value
const (
PermitDefault = iota
PermitAuth
PermitSuper
)
// PermitType permit type
type PermitType int
// Permission descript modules and rules
type Permission struct {
Name string
Permit PermitType
Des string
}
// rules
var (
Rules = map[string]*Permission{
UserView: {Name: "UserView", Permit: PermitSuper, Des: "用户查看"},
UserEdit: {Name: "UserEdit", Permit: PermitSuper, Des: "用户管理"},
UserAudit: {Name: "UserAudit", Permit: PermitSuper, Des: "权限审核"},
EcodeView: {Name: "EcodeView", Permit: PermitDefault, Des: "错误码查看"},
EcodeEdit: {Name: "EcodeEdit", Permit: PermitDefault, Des: "错误码编辑"},
DatabusKeyView: {Name: "DatabusKeyView", Permit: PermitDefault, Des: "Key查看"},
DatabusKeyEdit: {Name: "DatabusKeyEdit", Permit: PermitAuth, Des: "Key编辑"},
DatabusGroupView: {Name: "DatabusGroupView", Permit: PermitDefault, Des: "Group查看"},
DatabusGroupEdit: {Name: "DatabusGroupEdit", Permit: PermitAuth, Des: "Group修改"},
DatabusTopicView: {Name: "DatabusTopicView", Permit: PermitDefault, Des: "Topic查看"},
DatabusTopicEdit: {Name: "DatabusTopicEdit", Permit: PermitAuth, Des: "Topic编辑"},
DatabusNotifyView: {Name: "DatabusNotifyView", Permit: PermitDefault, Des: "Notify查看"},
DatabusNotifyEdit: {Name: "DatabusNotifyEdit", Permit: PermitAuth, Des: "Notify编辑"},
DatabusGroupApply: {Name: "DatabusGroupApply", Permit: PermitAuth, Des: "Group审核"},
DapperView: {Name: "DapperView", Permit: PermitDefault, Des: "Dapper查询"},
CanalView: {Name: "CanalView", Permit: PermitDefault, Des: "Canal查看"},
CanalEdit: {Name: "CanalEdit", Permit: PermitAuth, Des: "Canal编辑"},
ConfigView: {Name: "ConfigView", Permit: PermitDefault, Des: "配置列表查看"},
ConfigSearchView: {Name: "ConfigSearchView", Permit: PermitAuth, Des: "搜索列表查看"},
ConfigPublicView: {Name: "ConfigPublicView", Permit: PermitDefault, Des: "公共配置查看"},
DiscoveryView: {Name: "DiscoveryView", Permit: PermitDefault, Des: "Discovery查看"},
AppView: {Name: "AppView", Permit: PermitDefault, Des: "APP查看"},
AppEdit: {Name: "AppEdit", Permit: PermitAuth, Des: "APP编辑"},
AppAuthView: {Name: "AppAuthView", Permit: PermitAuth, Des: "APP鉴权查看"},
AppCallerSearch: {Name: "AppCallerSearch", Permit: PermitAuth, Des: "APP调用方查询"},
PlatformSearchView: {Name: "PlatformSearchView", Permit: PermitAuth, Des: "平台搜索"},
PlatformReplyView: {Name: "PlatformReplyView", Permit: PermitAuth, Des: "平台评论"},
PlatformTagView: {Name: "PlatformTagView", Permit: PermitAuth, Des: "Tag"},
CacheOpsView: {Name: "CacheOpsView", Permit: PermitAuth, Des: "overlord缓存集群管理"},
NeedVerify: {Name: "NeedVerify", Permit: PermitSuper, Des: "需求建议审核"},
OpenView: {Name: "OpenView", Permit: PermitAuth, Des: "open鉴权查看"},
PerformanceManager: {Name: "PerformanceManager", Permit: PermitDefault, Des: "性能管理"},
BFSView: {Name: "BFSView", Permit: PermitAuth, Des: "BFS查看"},
BFSEdit: {Name: "BFSEdit", Permit: PermitAuth, Des: "BFS编辑"},
}
)
// TableName case tablename
func (*Rule) TableName() string {
return "user_rule"
}
// TableName case tablename
func (*Apply) TableName() string {
return "user_apply"
}
// Rule rule model
type Rule struct {
ID int64 `gorm:"column:id" json:"id"`
UserID int64 `gorm:"column:user_id" json:"user_id"`
Rule string `gorm:"column:rule" json:"rule"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}
// Apply user apply
type Apply struct {
ID int64 `gorm:"column:id" json:"id"`
UserID int64 `gorm:"column:user_id" json:"user_id" params:"user_id"`
Rules string `gorm:"column:rules" json:"rules" params:"rules"`
Admin string `gorm:"column:admin" json:"admin" params:"admin"`
Status int8 `gorm:"column:status" json:"status" `
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}
// Applies ...
type Applies struct {
ID int64 `gorm:"column:id" json:"id"`
UserID int64 `gorm:"column:user_id" json:"user_id"`
UserName string `gorm:"column:username" json:"username"`
Rules string `gorm:"column:rules" json:"rules"`
Status string `gorm:"column:status" json:"status"`
}

View File

@@ -0,0 +1,39 @@
package user
import (
"go-common/library/time"
)
// TableName case tablename
func (*User) TableName() string {
return "user"
}
// User user model
type User struct {
ID int64 `gorm:"column:id" json:"id" params:"id;Min(1)"`
UserName string `gorm:"column:username" json:"username" params:"username"`
NickName string `gorm:"column:nickname" json:"nickname" params:"nickname"`
Email string `gorm:"column:email" json:"email" params:"email"`
Phone string `gorm:"column:phone" json:"phone" params:"phone"`
Status int8 `gorm:"column:status" json:"status" params:"status"`
AvatarURL string `gorm:"-" json:"avatar_url"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"-"`
}
// Pager user pager
type Pager struct {
Total int64 `json:"total"`
Pn int `params:"pn" default:"1"`
Ps int `params:"ps" default:"20"`
Items []*User `json:"items"`
}
// Result contains user and modules and rules.
type Result struct {
Super bool `json:"superman"`
Env string `json:"env"`
User *User `json:"user"`
Rules []string `json:"rules"`
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"dashboard.go",
"rank.go",
"ut.go",
],
importpath = "go-common/app/admin/main/apm/model/ut",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,56 @@
package ut
import (
"go-common/library/time"
"sync"
)
// TableName .
func (*App) TableName() string {
return "ut_app"
}
// App ..
type App struct {
ID int64 `gorm:"column:id" json:"id"`
Path string `gorm:"column:path" json:"path"`
Owner string `gorm:"column:owner" json:"owner"`
HasUt int `gorm:"column:has_ut" json:"has_ut"`
Link string `gorm:"-" json:"link"`
Coverage float64 `gorm:"coverage"`
CTime time.Time `gorm:"column:ctime" json:"ctime"`
MTime time.Time `gorm:"column:mtime" json:"mtime"`
}
// AppReq .
type AppReq struct {
HasUt int `form:"has_ut"`
Path string `form:"path"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" defalut:"20"`
}
// Department .
type Department struct {
Name string
Total int64
Access int64
Coverage float64
}
// AppsCache apps cache.
type AppsCache struct {
Slice []*App
Map map[string]*App
Owner map[string][]*App
Dept map[string]*Department
sync.Mutex
}
//PathsByOwner get app paths by owner.
func (apps *AppsCache) PathsByOwner(owner string) (paths []string) {
for _, app := range apps.Owner[owner] {
paths = append(paths, app.Path)
}
return
}

Some files were not shown because too many files have changed in this diff Show More