support i18n (#431)

master
qinyening 4 years ago committed by GitHub
parent 82dadb31b5
commit 74e85cdadc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,63 @@
{
"zh": {
"stra not found": "聚合策略为找到",
"unauthorized": "用户未授权",
"same stra name %s in node": "同节点下策略名称 %s 已存在",
"collect type not support": "采集类型不合法",
"[%s] is blank": "参数[%s]值不能为空",
"cannot convert %s to int64": "%s 无法转为 int64 类型",
"cannot convert %s to int": "%s 无法转为 int 类型",
"arg[%s] not found": "参数[%s]没找到",
"cannot retrieve node[%d]: %v": "获取不到节点[%d],原因:%v",
"no such node[%d]": "节点[%d]不存在",
"no such task[id:%d]": "任务[%d]不存在",
"no such task tpl[id:%d]": "任务模板[%d]不存在",
"cannot retrieve screen[%d]: %v": "获取不到大盘[%d],原因:%v",
"no such screen[%d]": "大盘[%d]不存在",
"cannot retrieve subclass[%d]: %v": "获取不到大盘分组[%d],原因:%v",
"no such subclass[%d]": "大盘分组[%d]不存在",
"cannot retrieve chart[%d]: %v": "获取不到大盘图表[%d],原因:%v",
"no such chart[%d]": "大盘图表[%d]不存在",
"cannot retrieve eventCur[%d]: %v": "获取不到未恢复告警事件[%d],原因:%v",
"no such eventCur[%d]": "未恢复告警事件[%d]不存在",
"cannot retrieve event[%d]: %v": "获取不到告警事件[%d],原因:%v",
"no such event[%d]": "告警事件[%d]不存在",
"cannot retrieve user[%d]: %v": "获取不到用户[%d],原因:%v",
"no such user[%d]": "用户[%d]不存在",
"no such user: %s": "用户[%s]不存在",
"cannot retrieve team[%d]: %v": "获取不到团队[%d],原因:%v",
"no such team[%d]": "团队[%d]不存在",
"cannot retrieve role[%d]: %v": "获取不到角色[%d],原因:%v",
"no such role[%d]": "角色[%d]不存在",
"no such NodeCate[id:%d]": "节点类型[%d]没找到",
"no such field": "扩展字段为找到",
"field_type cannot modify": "字段类型不能被修改",
"arg[endpoints] empty": "参数不能[endpoints]为空",
"arg[cur_nid_paths] empty": "参数不能[cur_nid_paths]为空",
"arg[tags] empty": "参数不能[tags]为空",
"arg[hosts] empty": "参数不能[hosts]为空",
"arg[btime,etime] empty": "参数[btime,etime]不合规范",
"arg[name] empty": "参数[name]不合规范",
"arg[name] is blank": "参数[名称]不能为空",
"arg[ids] is empty": "参数[ids]不能为空",
"%s invalid": "%s 不符合规范",
"%s too long > 64": "%s 超过64长度限制",
"arg[%s] too long > %d": "参数 %s 长度不能超过 %d",
"cate is blank": "节点分类不能为空",
"uuid is blank": "uuid不能为空",
"ident is blank": "唯一标识不能为空",
"tenant is blank": "租户不能为空",
"ids is blank": "ids不能为空",
"items empty": "提交内容不能为空",
"url param[%s] is blank": "url参数[%s]不能为空",
"query param[%s] is necessary": "query参数[%s]不能为空",
"ident legal characters: [a-z0-9_-]": "唯一标识英文只能字母开头,包括数字、中划线、下划线",
"ident length should be less than 32": "唯一标识长度需小于32",
"cannot modify tenant's node-category": "租户分类不允许修改",
"cannot modify node-category to tenant": "节点分类不允许修改为租户",
"node is managed by other system": "租户正在被系统系统使用",
"resources not found by %s": "通过 %s 没有找到资源",
"cannot delete root user": "root用户不能删除",
"user not found": "用户未找到"
}
}

@ -37,6 +37,7 @@ require (
go.uber.org/automaxprocs v1.3.0 // indirect
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/text v0.3.3
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ldap.v3 v3.1.0

@ -16,6 +16,7 @@ import (
"github.com/didi/nightingale/src/models"
"github.com/didi/nightingale/src/modules/ams/config"
"github.com/didi/nightingale/src/modules/ams/http"
"github.com/didi/nightingale/src/toolkits/i18n"
)
var (
@ -42,6 +43,8 @@ func init() {
os.Exit(0)
}
i18n.Init()
runner.Init()
fmt.Println("runner.cwd:", runner.Cwd)
fmt.Println("runner.hostname:", runner.Hostname)
@ -55,6 +58,8 @@ func main() {
// 初始化数据库和相关数据
models.InitMySQL("rdb", "ams")
i18n.Init(config.Config.I18n)
http.Start()
endingProc()

@ -4,13 +4,16 @@ import (
"fmt"
"github.com/didi/nightingale/src/common/loggeri"
"github.com/didi/nightingale/src/toolkits/i18n"
"github.com/toolkits/pkg/file"
)
type ConfigT struct {
Logger loggeri.Config `yaml:"logger"`
HTTP httpSection `yaml:"http"`
Tokens []string `yaml:"tokens"`
Logger loggeri.Config `yaml:"logger"`
HTTP httpSection `yaml:"http"`
Tokens []string `yaml:"tokens"`
I18n i18n.I18nSection `yaml:"i18n"`
}
type httpSection struct {
@ -35,6 +38,14 @@ func Parse() error {
}
Config = &c
if Config.I18n.DictPath == "" {
Config.I18n.DictPath = "etc/dict.json"
}
if Config.I18n.Lang == "" {
Config.I18n.Lang = "zh"
}
fmt.Println("config.file:", ymlFile)
return nil

@ -7,6 +7,7 @@ import (
"github.com/toolkits/pkg/errors"
"github.com/didi/nightingale/src/models"
"github.com/didi/nightingale/src/toolkits/i18n"
)
func dangerous(v interface{}) {
@ -14,7 +15,7 @@ func dangerous(v interface{}) {
}
func bomb(format string, a ...interface{}) {
errors.Bomb(format, a...)
errors.Bomb(i18n.Sprintf(format, a...))
}
func bind(c *gin.Context, ptr interface{}) {

@ -13,15 +13,15 @@ func hostFieldNew(c *gin.Context) {
bind(c, &obj)
if obj.FieldIdent == "" {
bomb("field_ident is blank")
bomb("[%s] is blank", "field_ident")
}
if obj.FieldName == "" {
bomb("field_name is blank")
bomb("[%s] is blank", "field_name")
}
if obj.FieldType == "" {
bomb("field_type is blank")
bomb("[%s] is blank", "field_type")
}
if obj.FieldCate == "" {

@ -7,13 +7,15 @@ import (
"github.com/didi/nightingale/src/common/identity"
"github.com/didi/nightingale/src/common/loggeri"
"github.com/didi/nightingale/src/toolkits/i18n"
)
type ConfigT struct {
Logger loggeri.Config `yaml:"logger"`
HTTP httpSection `yaml:"http"`
Tokens []string `yaml:"tokens"`
Output outputSection `yaml:"output"`
Logger loggeri.Config `yaml:"logger"`
HTTP httpSection `yaml:"http"`
Tokens []string `yaml:"tokens"`
Output outputSection `yaml:"output"`
I18n i18n.I18nSection `yaml:"i18n"`
}
type httpSection struct {
@ -43,6 +45,15 @@ func Parse() error {
}
Config = &c
if Config.I18n.DictPath == "" {
Config.I18n.DictPath = "etc/dict.json"
}
if Config.I18n.Lang == "" {
Config.I18n.Lang = "zh"
}
fmt.Println("config.file:", ymlFile)
return identity.Parse()

@ -8,6 +8,7 @@ import (
"github.com/toolkits/pkg/errors"
"github.com/didi/nightingale/src/models"
"github.com/didi/nightingale/src/toolkits/i18n"
)
func dangerous(v interface{}) {
@ -15,9 +16,8 @@ func dangerous(v interface{}) {
}
func bomb(format string, a ...interface{}) {
errors.Bomb(format, a...)
errors.Bomb(i18n.Sprintf(format, a...))
}
func bind(c *gin.Context, ptr interface{}) {
dangerous(c.ShouldBindJSON(ptr))
}
@ -212,7 +212,7 @@ func Node(id int64) *models.Node {
dangerous(err)
if node == nil {
bomb("no such node[id:%d]", id)
bomb("no such node[%d]", id)
}
return node

@ -19,6 +19,7 @@ import (
"github.com/didi/nightingale/src/modules/job/http"
"github.com/didi/nightingale/src/modules/job/rpc"
"github.com/didi/nightingale/src/modules/job/timer"
"github.com/didi/nightingale/src/toolkits/i18n"
)
var (
@ -82,6 +83,8 @@ func main() {
// 将task_host_doing表缓存到内存里减少DB压力
timer.CacheHostDoing()
i18n.Init(config.Config.I18n)
go rpc.Start()
http.Start()

@ -5,6 +5,8 @@ import (
"fmt"
"sync"
"github.com/didi/nightingale/src/toolkits/i18n"
"github.com/spf13/viper"
"github.com/toolkits/pkg/file"
)
@ -26,6 +28,7 @@ type ConfYaml struct {
Notify map[string][]string `yaml:"notify"`
Link linkSection `yaml:"link"`
IndexMod string `yaml:"indexMod"`
I18n i18n.I18nSection `yaml:"i18n"`
}
type mergeSection struct {
@ -141,6 +144,9 @@ func Parse(ymlfile string) error {
viper.SetDefault("habits.identity", "ip")
viper.SetDefault("i18n.dictPath", "etc/dict.json")
viper.SetDefault("i18n.lang", "zh")
viper.SetDefault("redis.idle", 5)
viper.SetDefault("redis.timeout", map[string]int{
"conn": 500,

@ -21,7 +21,7 @@ func GetCookieUser() gin.HandlerFunc {
}
if username == "" {
errors.Bomb("unauthorized")
bomb("unauthorized")
}
c.Set("username", username)
@ -61,7 +61,7 @@ func CheckHeaderToken() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("X-Srv-Token")
if token != internalToken && !slice.ContainsString(config.Get().Tokens, token) {
errors.Bomb("token[%s] invalid", token)
bomb("token[%s] invalid", token)
}
c.Next()
}

@ -16,7 +16,7 @@ func aggrCalcPost(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_aggr_write", stra.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
stra.Creator = username
@ -26,7 +26,7 @@ func aggrCalcPost(c *gin.Context) {
oldStra, _ := models.AggrCalcGet("nid=? and new_metric=?", stra.Nid, stra.NewMetric)
if oldStra != nil {
errors.Bomb("同节点下指标计算 新指标名称 %s 已存在", stra.NewMetric)
bomb("同节点下指标计算 新指标名称 %s 已存在", stra.NewMetric)
}
err = stra.Save()
@ -42,7 +42,7 @@ func aggrCalcPut(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_aggr_write", stra.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
stra.LastUpdator = username
@ -50,7 +50,7 @@ func aggrCalcPut(c *gin.Context) {
oldStra, _ := models.AggrCalcGet("nid=? and new_metric=?", stra.Nid, stra.NewMetric)
if oldStra != nil && oldStra.Id != stra.Id {
errors.Bomb("同节点下指标计算 新指标名称 %s 已存在", stra.NewMetric)
bomb("同节点下指标计算 新指标名称 %s 已存在", stra.NewMetric)
}
err = stra.Update("new_metric", "new_step", "groupby", "raw_metrics", "global_operator",
@ -80,7 +80,7 @@ func aggrCalcsDel(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_aggr_write", stra.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
}
@ -97,7 +97,7 @@ func aggrCalcGet(c *gin.Context) {
stra, err := models.AggrCalcGet("id=?", id)
errors.Dangerous(err)
if stra == nil {
errors.Bomb("stra not found")
bomb("stra not found")
}
err = stra.Decode()

@ -23,7 +23,7 @@ func chartPost(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(loginUsername(c), "mon_screen_write", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
chart := models.Chart{
@ -55,7 +55,7 @@ func chartPut(c *gin.Context) {
can, err := canWriteChart(f.SubclassId, loginUsername(c))
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
chart.Configs = f.Configs
@ -81,7 +81,7 @@ func chartWeightsPut(c *gin.Context) {
can, err := canWriteChart(chart.SubclassId, loginUsername(c))
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
}
@ -99,7 +99,7 @@ func chartDel(c *gin.Context) {
can, err := canWriteChart(chart.SubclassId, loginUsername(c))
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
errors.Dangerous(chart.Del())

File diff suppressed because it is too large Load Diff

@ -4,16 +4,25 @@ import (
"strconv"
"github.com/didi/nightingale/src/models"
"github.com/didi/nightingale/src/toolkits/i18n"
"github.com/gin-gonic/gin"
"github.com/toolkits/pkg/errors"
)
func dangerous(v interface{}) {
errors.Dangerous(v)
}
func bomb(format string, a ...interface{}) {
errors.Bomb(i18n.Sprintf(format, a...))
}
func urlParamStr(c *gin.Context, field string) string {
val := c.Param(field)
if val == "" {
errors.Bomb("[%s] is blank", field)
bomb("[%s] is blank", field)
}
return val
@ -23,7 +32,7 @@ func urlParamInt64(c *gin.Context, field string) int64 {
strval := urlParamStr(c, field)
intval, err := strconv.ParseInt(strval, 10, 64)
if err != nil {
errors.Bomb("cannot convert %s to int64", strval)
bomb("cannot convert %s to int64", strval)
}
return intval
@ -45,7 +54,7 @@ func queryStr(c *gin.Context, key string, defaultVal string) string {
func mustQueryStr(c *gin.Context, key string) string {
val := c.Query(key)
if val == "" {
errors.Bomb("arg[%s] not found", key)
bomb("arg[%s] not found", key)
}
return val
@ -56,7 +65,7 @@ func mustQueryInt(c *gin.Context, key string) int {
intv, err := strconv.Atoi(strv)
if err != nil {
errors.Bomb("cannot convert [%s] to int", strv)
bomb("cannot convert [%s] to int", strv)
}
return intv
@ -67,7 +76,7 @@ func mustQueryInt64(c *gin.Context, key string) int64 {
intv, err := strconv.ParseInt(strv, 10, 64)
if err != nil {
errors.Bomb("cannot convert [%s] to int64", strv)
bomb("cannot convert [%s] to int64", strv)
}
return intv
@ -81,7 +90,7 @@ func queryInt(c *gin.Context, key string, defaultVal int) int {
intv, err := strconv.Atoi(strv)
if err != nil {
errors.Bomb("cannot convert [%s] to int", strv)
bomb("cannot convert [%s] to int", strv)
}
return intv
@ -95,7 +104,7 @@ func queryInt64(c *gin.Context, key string, defaultVal int64) int64 {
intv, err := strconv.ParseInt(strv, 10, 64)
if err != nil {
errors.Bomb("cannot convert [%s] to int64", strv)
bomb("cannot convert [%s] to int64", strv)
}
return intv
@ -150,7 +159,7 @@ func loginUsername(c *gin.Context) string {
username2 := cookieUsername(c)
if username2 == "" {
errors.Bomb("unauthorized")
bomb("unauthorized")
}
return username2
@ -159,11 +168,11 @@ func loginUsername(c *gin.Context) string {
func mustNode(id int64) *models.Node {
node, err := models.NodeGet("id=?", id)
if err != nil {
errors.Bomb("cannot retrieve node[%d]: %v", id, err)
bomb("cannot retrieve node[%d]: %v", id, err)
}
if node == nil {
errors.Bomb("no such node[%d]", id)
bomb("no such node[%d]", id)
}
return node
@ -172,11 +181,11 @@ func mustNode(id int64) *models.Node {
func mustScreen(id int64) *models.Screen {
screen, err := models.ScreenGet("id", id)
if err != nil {
errors.Bomb("cannot retrieve screen[%d]: %v", id, err)
bomb("cannot retrieve screen[%d]: %v", id, err)
}
if screen == nil {
errors.Bomb("no such screen[%d]", id)
bomb("no such screen[%d]", id)
}
return screen
@ -185,11 +194,11 @@ func mustScreen(id int64) *models.Screen {
func mustScreenSubclass(id int64) *models.ScreenSubclass {
subclass, err := models.ScreenSubclassGet("id", id)
if err != nil {
errors.Bomb("cannot retrieve subclass[%d]: %v", id, err)
bomb("cannot retrieve subclass[%d]: %v", id, err)
}
if subclass == nil {
errors.Bomb("no such subclass[%d]", id)
bomb("no such subclass[%d]", id)
}
return subclass
@ -198,11 +207,11 @@ func mustScreenSubclass(id int64) *models.ScreenSubclass {
func mustChart(id int64) *models.Chart {
chart, err := models.ChartGet("id", id)
if err != nil {
errors.Bomb("cannot retrieve chart[%d]: %v", id, err)
bomb("cannot retrieve chart[%d]: %v", id, err)
}
if chart == nil {
errors.Bomb("no such chart[%d]", id)
bomb("no such chart[%d]", id)
}
return chart
@ -211,11 +220,11 @@ func mustChart(id int64) *models.Chart {
func mustEventCur(id int64) *models.EventCur {
eventCur, err := models.EventCurGet("id", id)
if err != nil {
errors.Bomb("cannot retrieve eventCur[%d]: %v", id, err)
bomb("cannot retrieve eventCur[%d]: %v", id, err)
}
if eventCur == nil {
errors.Bomb("no such eventCur[%d]", id)
bomb("no such eventCur[%d]", id)
}
return eventCur
@ -224,11 +233,11 @@ func mustEventCur(id int64) *models.EventCur {
func mustEvent(id int64) *models.Event {
eventCur, err := models.EventGet("id", id)
if err != nil {
errors.Bomb("cannot retrieve event[%d]: %v", id, err)
bomb("cannot retrieve event[%d]: %v", id, err)
}
if eventCur == nil {
errors.Bomb("no such event[%d]", id)
bomb("no such event[%d]", id)
}
return eventCur

@ -25,15 +25,15 @@ func (f MaskconfForm) Validate() {
mustNode(f.Nid)
if f.Category == 1 && (f.Endpoints == nil || len(f.Endpoints) == 0) {
errors.Bomb("arg[endpoints] empty")
bomb("arg[endpoints] empty")
}
if f.Category == 2 && len(f.CurNidPaths) == 0 {
errors.Bomb("arg[cur_nid_paths] empty")
bomb("arg[cur_nid_paths] empty")
}
if f.Btime >= f.Etime {
errors.Bomb("args[btime,etime] invalid")
bomb("args[btime,etime] invalid")
}
if f.Tags == "" {
@ -44,7 +44,7 @@ func (f MaskconfForm) Validate() {
for i := 0; i < len(tagsList); i++ {
kv := strings.Split(tagsList[i], "=")
if len(kv) != 2 {
errors.Bomb("arg[tags] invalid")
bomb("arg[tags] invalid")
}
}
}
@ -55,7 +55,7 @@ func maskconfPost(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(loginUsername(c), "mon_maskconf_create", f.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
f.Validate()
@ -106,7 +106,7 @@ func maskconfDel(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(loginUsername(c), "mon_maskconf_delete", mask.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
renderMessage(c, models.MaskconfDel(id))
@ -117,13 +117,13 @@ func maskconfPut(c *gin.Context) {
errors.Dangerous(err)
if mc == nil {
errors.Bomb("maskconf is nil")
bomb("maskconf is nil")
}
can, err := models.UsernameCandoNodeOp(loginUsername(c), "mon_maskconf_modify", mc.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
var f MaskconfForm

@ -17,19 +17,19 @@ type ScreenForm struct {
func screenNameValidate(name string) {
if str.Dangerous(name) {
errors.Bomb("arg[name] is dangerous")
bomb("arg[name] is dangerous")
}
if len(name) > 250 {
errors.Bomb("arg[name] too long")
bomb("arg[name] too long")
}
if len(name) == 0 {
errors.Bomb("arg[name] is blank")
bomb("arg[name] is blank")
}
if strings.ContainsAny(name, "/%") {
errors.Bomb("arg[name] invalid")
bomb("arg[name] invalid")
}
}
@ -42,7 +42,7 @@ func screenPost(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_create", node.Id)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
screenNameValidate(f.Name)
@ -64,7 +64,7 @@ func screenGets(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_view", nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
objs, err := models.ScreenGets(nid)
@ -79,7 +79,7 @@ func screenGet(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_view", obj.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
obj.NodePath = node.Path
@ -102,7 +102,7 @@ func screenPut(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_modify", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
node := mustNode(f.NodeId)
@ -121,7 +121,7 @@ func screenDel(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_delete", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
errors.Dangerous(screen.Del())
@ -142,11 +142,11 @@ type ScreenSubclassForm struct {
func (f ScreenSubclassForm) Validate() {
if str.Dangerous(f.Name) {
errors.Bomb("name invalid")
bomb("arg[name] invalid")
}
if strings.ContainsAny(f.Name, "/%") {
errors.Bomb("name invalid")
bomb("arg[name] invalid")
}
}
@ -160,7 +160,7 @@ func screenSubclassPost(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(loginUsername(c), "mon_screen_create", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
screenNameValidate(f.Name)
@ -188,7 +188,7 @@ func screenSubclassPut(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_modify", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
}
@ -213,7 +213,7 @@ func screenSubclassLocPut(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_screen_modify", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
}
@ -232,7 +232,7 @@ func screenSubclassDel(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(loginUsername(c), "mon_screen_delete", screen.NodeId)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
if subclass == nil {

@ -16,7 +16,7 @@ func straPost(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_stra_create", stra.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
stra.Creator = username
@ -26,7 +26,7 @@ func straPost(c *gin.Context) {
oldStra, _ := models.StraGet("name", stra.Name)
if oldStra != nil && oldStra.Nid == stra.Nid {
errors.Bomb("同节点下策略名称 %s 已存在", stra.Name)
bomb("同节点下策略名称 %s 已存在", stra.Name)
}
errors.Dangerous(stra.Save())
@ -48,7 +48,7 @@ func straPut(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_stra_modify", stra.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
stra.LastUpdator = username
@ -56,7 +56,7 @@ func straPut(c *gin.Context) {
oldStra, _ := models.StraGet("name", stra.Name)
if oldStra != nil && oldStra.Id != stra.Id && oldStra.Nid == stra.Nid {
errors.Bomb("同节点下策略名称 %s 已存在", stra.Name)
bomb("同节点下策略名称 %s 已存在", stra.Name)
}
s, err := models.StraGet("id", stra.Id)
@ -83,7 +83,7 @@ func strasDel(c *gin.Context) {
can, err := models.UsernameCandoNodeOp(username, "mon_stra_delete", stra.Nid)
errors.Dangerous(err)
if !can {
errors.Bomb("permission deny")
bomb("permission deny")
}
}
@ -100,7 +100,7 @@ func straGet(c *gin.Context) {
stra, err := models.StraGet("id", sid)
errors.Dangerous(err)
if stra == nil {
errors.Bomb("stra not found")
bomb("stra not found")
}
err = stra.Decode()

@ -16,6 +16,7 @@ import (
"github.com/didi/nightingale/src/modules/monapi/http"
"github.com/didi/nightingale/src/modules/monapi/redisc"
"github.com/didi/nightingale/src/modules/monapi/scache"
"github.com/didi/nightingale/src/toolkits/i18n"
_ "github.com/go-sql-driver/mysql"
@ -65,6 +66,8 @@ func main() {
scache.Init()
i18n.Init(config.Get().I18n)
if err := scache.CheckJudge(); err != nil {
logger.Errorf("check judge fail: %v", err)
}

@ -6,6 +6,7 @@ import (
"github.com/toolkits/pkg/file"
"github.com/didi/nightingale/src/common/loggeri"
"github.com/didi/nightingale/src/toolkits/i18n"
)
type ConfigT struct {
@ -19,6 +20,7 @@ type ConfigT struct {
RabbitMQ rabbitmqSection `yaml:"rabbitmq"`
WeChat wechatSection `yaml:"wechat"`
Captcha bool `yaml:"captcha"`
I18n i18n.I18nSection `yaml:"i18n"`
}
type wechatSection struct {
@ -115,6 +117,14 @@ func Parse() error {
Config = &c
fmt.Println("config.file:", ymlFile)
if Config.I18n.DictPath == "" {
Config.I18n.DictPath = "etc/dict.json"
}
if Config.I18n.Lang == "" {
Config.I18n.Lang = "zh"
}
if err = parseOps(); err != nil {
return err
}

@ -230,7 +230,7 @@ func (f *loginInput) validate() {
bomb("%s invalid", f.Username)
}
if len(f.Username) > 64 {
bomb("%s too long", f.Username)
bomb("%s too long > 64", f.Username)
}
}
}

@ -8,6 +8,7 @@ import (
"github.com/toolkits/pkg/errors"
"github.com/didi/nightingale/src/models"
"github.com/didi/nightingale/src/toolkits/i18n"
)
func dangerous(v interface{}) {
@ -15,7 +16,7 @@ func dangerous(v interface{}) {
}
func bomb(format string, a ...interface{}) {
errors.Bomb(format, a...)
errors.Bomb(i18n.Sprintf(format, a...))
}
func bind(c *gin.Context, ptr interface{}) {
@ -110,7 +111,7 @@ func renderMessage(c *gin.Context, v interface{}) {
switch t := v.(type) {
case string:
c.JSON(200, gin.H{"err": t})
c.JSON(200, gin.H{"err": i18n.Sprintf(t)})
case error:
c.JSON(200, gin.H{"err": t.Error()})
}
@ -274,7 +275,7 @@ func Node(id int64) *models.Node {
dangerous(err)
if node == nil {
bomb("no such node[id:%d]", id)
bomb("no such node[%d]", id)
}
return node

@ -20,23 +20,23 @@ type nodeCatePostForm struct {
func (f nodeCatePostForm) Validate() {
if f.Ident == "" {
bomb("ident is blank")
bomb("[%s] is blank", "ident")
}
if f.Name == "" {
bomb("name is blank")
bomb("[%s] is blank", "name")
}
if len(f.Ident) > 32 {
bomb("arg[ident] too long")
bomb("arg[%s] too long > %d", "ident", 32)
}
if len(f.Name) > 255 {
bomb("arg[name] too long")
bomb("arg[%s] too long > %d", "name", 255)
}
if !str.IsMatch(f.Ident, "[a-z]+") {
bomb("arg[ident] invalid")
bomb("arg[%s] invalid", "ident")
}
if str.Dangerous(f.Name) {
@ -65,7 +65,7 @@ type nodeCatePutForm struct {
func (f nodeCatePutForm) Validate() {
if len(f.Name) > 255 {
bomb("arg[name] too long")
bomb("arg[%s] too long > %d", "name", 255)
}
if str.Dangerous(f.Name) {

@ -337,13 +337,13 @@ func resourceBindNode(c *gin.Context) {
ids, err = models.ResourceIdsByUUIDs(f.Items)
dangerous(err)
if len(ids) == 0 {
bomb("resources not found by uuid")
bomb("resources not found by %s", "uuic")
}
} else if f.Field == "ident" {
ids, err = models.ResourceIdsByIdents(f.Items)
dangerous(err)
if len(ids) == 0 {
bomb("resources not found by ident")
bomb("resources not found by %s", "ident")
}
} else {
bomb("field[%s] not supported", f.Field)

@ -213,7 +213,7 @@ func belongTeamsGet(c *gin.Context) {
dangerous(err)
if user == nil {
bomb("no such username[%s]", username)
bomb("no such user: %s", username)
}
var ids []int64
@ -246,7 +246,7 @@ func isTeamMember(c *gin.Context) {
dangerous(err)
if user == nil {
bomb("no such username[%s]", username)
bomb("no such user: %s", username)
}
team, err := models.TeamGet("ident=?", teamIdent)

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

Loading…
Cancel
Save