From e9a5e079f0e27831a1df6547f99cc838f12a5d59 Mon Sep 17 00:00:00 2001 From: shaoying Date: Sat, 26 Jan 2019 22:46:14 +0800 Subject: [PATCH] opt ssh&aaa Change-Id: I283075b3d1d04e48f50c69686bb31b2dc06087b1 --- src/contexts/aaa/aaa.go | 408 +++++++---------------------------- src/contexts/cli/cli.go | 2 +- src/contexts/ctx/ctx_init.go | 288 +++++++++++++------------ src/contexts/ctx/ctx_type.go | 32 +++ src/contexts/log/log.go | 2 + src/contexts/nfs/nfs.go | 12 +- src/contexts/ssh/ssh.go | 97 +++++---- src/contexts/tcp/tcp.go | 28 ++- src/contexts/web/web.go | 31 ++- src/examples/code/code.go | 46 +++- src/toolkit/kit.go | 160 +++++++++----- 11 files changed, 529 insertions(+), 577 deletions(-) diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index 1b609f34..c7cbabe2 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -13,11 +13,9 @@ import ( "encoding/hex" "encoding/pem" "fmt" - "io" "io/ioutil" "math/big" "math/rand" - "os" "strings" "time" "toolkit" @@ -129,6 +127,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "userrole": map[string]interface{}{"public": true}, "password": map[string]interface{}{"secrete": true, "single": true}, "uuid": map[string]interface{}{"secrete": true, "single": true}, + "ppid": map[string]interface{}{"secrete": true, "single": true}, }, Help: "散列"}, "secrete_key": &ctx.Config{Name: "secrete_key", Value: map[string]interface{}{"password": 1, "uuid": 1}, Help: "私钥文件"}, @@ -138,37 +137,13 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "key": &ctx.Config{Name: "key", Value: "etc/pem/key.pem", Help: "私钥文件"}, }, Commands: map[string]*ctx.Command{ - "hash": &ctx.Command{Name: "hash type data... time rand", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "hash": &ctx.Command{Name: "hash [meta...]", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { m.Cmdy("ctx.config", "hash") return } - if arg[0] == "file" { - if f, e := os.Open(arg[1]); e == nil { - hash := md5.New() - io.Copy(hash, f) - h := hash.Sum(nil) - arg[1] = hex.EncodeToString(h[:]) - } - } - - meta := []string{} - for _, v := range arg { - switch v { - case "time": - v = time.Now().Format(m.Conf("time_format")) - case "rand": - v = fmt.Sprintf("%d", rand.Int()) - case "": - continue - } - meta = append(meta, v) - } - - h := md5.Sum(Input(strings.Join(meta, ""))) - hs := hex.EncodeToString(h[:]) - + hs, meta := kit.Hash(arg) m.Log("info", "%s: %v", hs, meta) m.Confv("hash", hs, meta) m.Echo(hs) @@ -322,7 +297,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Add("append", "create_time", node["create_time"]) } }) - m.Table() + m.Set("result").Table() break } else if i == len(arg)-1 { // 读取链接 if p == "" { @@ -349,8 +324,22 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } }) } - m.Table() + m.Set("result").Table() return + } else if i == len(arg)-2 { + if p != "" && arg[i] == "session" { + m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { + if node := m.Confm("auth", k); ship["type"].(string) == arg[i] && (ship["meta"] == arg[i+1] || strings.HasSuffix(k, arg[i+1]) || strings.HasPrefix(k, arg[i+1])) { + m.Add("append", "key", k) + m.Add("append", "ship", ship["ship"]) + m.Add("append", "type", node["type"]) + m.Add("append", "meta", node["meta"]) + m.Add("append", "create_time", node["create_time"]) + } + }) + m.Set("result").Table() + return + } } if arg[i] == "check" { @@ -382,6 +371,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", h := m.Cmdx("aaa.hash", meta) if !m.Confs("auth", h) { if m.Confs("auth_type", []string{arg[i], "single"}) && m.Cmds("aaa.auth", p, arg[i]) { + m.Set("result") return // 单点认证失败 } @@ -396,12 +386,10 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", if p != "" { // 创建父链接 chain = append(chain, map[string]string{"node": p, "ship": "1", "hash": h, "type": arg[i], "meta": meta[1]}) chain = append(chain, map[string]string{"node": h, "ship": "0", "hash": p, "type": t, "meta": ""}) - } else if t == "" && arg[i] == "session" { - defer func() { m.Set("result").Echo(h) }() } p, t, a = h, arg[i], meta[1] - m.Set("result").Echo(h) + m.Echo(h) case "node": // 节点操作 if i > len(arg)-1 { // 查看节点 m.Cmdy("aaa.config", "auth", p) @@ -462,30 +450,29 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } return }}, - "role": &ctx.Command{Name: "role [name [[componet] componet [[command] command]]]", Help: "用户角色", + "role": &ctx.Command{Name: "role [name [[componet] name [[command] name]]]", Help: "用户角色", Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { switch len(arg) { - case 0: + case 0: // 查看角色 Auto(m, "ship", "userrole") + case 1: // 查看组件 + Auto(m, "ship", "userrole", arg[0], "componet") + case 2: // 查看功能 + Auto(m, "ship", "userrole", arg[0], "componet", arg[1], "command") } return true }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { switch len(arg) { - case 0: + case 0: // 查看角色 m.Cmdy("aaa.auth", "ship", "userrole") - case 1: + case 1: // 查看组件 m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet") - case 2: - m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond") - case 3: - if arg[1] == "componet" { - m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2]) - } else { - m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond", arg[2]) - } - case 4: - default: + case 2: // 查看功能 + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "command") + case 3: // 查看接口 + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "command", arg[2], "componet") + default: // 添加接口 if arg[1] == "componet" && arg[3] == "command" { for _, v := range arg[4:] { m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2], "command", v) @@ -497,82 +484,62 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "user": &ctx.Command{Name: "user [role username password] [username]", Help: "用户认证", Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { switch len(arg) { - case 0: + case 0: // 查看用户 Auto(m, "ship", "username") + case 1: // 查看会话 + Auto(m, "ship", "username", arg[0], "session") } return true }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { switch len(arg) { - case 0: + case 0: // 查看用户 m.Cmdy("aaa.auth", "ship", "username") - case 1: - m.Cmd("aaa.auth", "ship", "username", arg[0], "userrole").CopyTo(m, "append") - case 3: + case 1: // 查看角色 + m.Cmdy("aaa.auth", "ship", "username", arg[0], "userrole") + case 2: // 查看会话 + m.Cmdy("aaa.auth", "ship", "username", arg[0], "session", arg[1]) + case 3: // 用户认证 if m.Cmds("aaa.auth", "ship", "username", arg[0]) && (arg[1] == "password" || arg[1] == "uuid") { m.Cmdy("aaa.auth", "username", arg[0], arg[1], arg[2]) break } fallthrough - default: + default: // 添加用户 for i := 1; i < len(arg); i += 2 { - if m.Cmd("aaa.auth", "ship", "username", arg[i], "userrole", arg[0]); i < len(arg)-1 { + if m.Cmdy("aaa.auth", "ship", "username", arg[i], "userrole", arg[0]); i < len(arg)-1 { m.Cmd("aaa.auth", "ship", "username", arg[i], "password", arg[i+1]) } } } return }}, - "sess": &ctx.Command{Name: "sess [sessid [username]]", Help: "会话管理", + "sess": &ctx.Command{Name: "sess [sessid [meta]|[username password password]]|[type ip ip]", Help: "会话管理", Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { switch len(arg) { - case 0: + case 0: // 查看会话 Auto(m, "ship", "session") - case 1: - m.Auto("username", "username", "查看用户") - m.Auto("userrole", "userrole", "查看角色") - m.Auto("bench", "bench", "查看空间") - m.Auto("ip", "ip", "查看设备") - m.Cmd("aaa.auth", arg[0], "ship", "username").Table(func(node map[string]string) { - m.Auto(node["meta"], node["type"], node["create_time"]) - }) + case 1: // 查看会话 + Auto(m, "ship", "session", arg[0]) } return true }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { switch len(arg) { - case 0: + case 0: // 查看会话 m.Cmdy("aaa.auth", "ship", "session") - case 1: + case 1: // 查看会话 m.Cmdy("aaa.auth", arg[0]) - - case 2: - switch arg[1] { - case "username", "ip", "bench": - m.Cmd("aaa.auth", arg[0], "ship", arg[1]).CopyTo(m, "append").Table() - - case "userrole": - m.Cmd("aaa.auth", arg[0], "ship", "username").Table(func(user map[string]string) { - m.Cmd("aaa.user", user).Table(func(role map[string]string) { - m.Add("append", "username", user["meta"]) - m.Add("append", "userrole", role["meta"]) - }) - }) - m.Table() - - default: - m.Cmd("aaa.auth", arg[0], "ship", "username", arg[1], "userrole").CopyTo(m, "append").Table() - } - - case 3: + case 2: // 查询会话 + m.Cmdy("aaa.auth", arg[0], "ship", arg[1]) + case 3: // 创建会话 m.Cmdy("aaa.auth", "ship", "session", arg[0], arg[1], arg[2]) - - case 4: + case 4: // 用户登录 m.Cmdy("aaa.auth", arg[0], "ship", "username", arg[1], arg[2], arg[3]) } return }}, - "work": &ctx.Command{Name: "work [sessid create|select]|[benchid] [right [userrole [componet name [command name [argument name]]]]]", Help: "工作任务", + "work": &ctx.Command{Name: "work [sessid create|select]|[benchid] [right [username [componet name [command name [argument name]]]]]", Help: "工作任务", Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (goon bool) { switch len(arg) { case 0: @@ -601,65 +568,45 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", return true }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { + if len(arg) == 0 { // 查看空间 m.Cmdy("aaa.auth", "ship", "bench") return } bid := "" switch m.Conf("auth", []string{arg[0], "type"}) { - case "session": - if len(arg) == 1 { - m.Confm("auth", []string{arg[0], "ship"}, func(key string, ship map[string]interface{}) { - m.Add("append", "key", key) - m.Add("append", "type", ship["type"]) - m.Add("append", "meta", ship["meta"]) - m.Add("append", "create_time", ship["create_time"]) - }) - m.Table() - return - } - switch arg[1] { - case "create": - bid, arg = m.Cmdx("aaa.auth", arg[0], "ship", "bench", arg[2]), arg[3:] - m.Cmd("aaa.auth", bid, "data", "name", "web") - defer func() { m.Set("result").Echo(bid) }() - case "select": - m.Cmd("aaa.auth", arg[0], "ship", "bench").Table(func(node map[string]string) { - if strings.Contains(node["meta"], arg[2]) || strings.HasPrefix(node["key"], arg[2]) || strings.HasSuffix(node["key"], arg[2]) { - bid = node["key"] - } - }) - arg = arg[3:] - } - case "bench": + case "session": // 创建空间 + bid, arg = m.Cmdx("aaa.auth", arg[0], "ship", "bench", arg[1]), arg[2:] + m.Cmd("aaa.auth", bid, "data", "name", "web") + defer func() { m.Set("result").Echo(bid) }() + case "bench": // 查询空间 bid, arg = arg[0], arg[1:] default: return } - if len(arg) == 0 { m.Echo(bid) return } switch arg[0] { - case "delete": + case "delete": // 删除空间 m.Cmd("aaa.auth", bid, "delete", "node") - case "rename": + case "rename": // 命名空间 m.Cmd("aaa.auth", bid, "data", "name", arg[1]) - case "right": + case "right": // 权限检查 m.Cmd("aaa.auth", "ship", "username", arg[1], "userrole").Table(func(node map[string]string) { - if node["meta"] == "root" { + if node["meta"] == "root" { // 超级用户 + m.Log("info", "root %s", arg[1]) m.Echo("true") - } else if len(arg) >= 4 { + } else if len(arg) >= 4 { // 功能权限 if m.Cmds("aaa.auth", bid, "ship", "check", arg[3]) { m.Echo("true") } else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "componet", arg[2], "check", arg[3]); kit.Right(cid) { m.Cmd("aaa.auth", bid, cid) m.Echo("true") } - } else if len(arg) >= 3 { + } else if len(arg) >= 3 { // 组件权限 if m.Cmds("aaa.auth", bid, "ship", "check", arg[2]) { m.Echo("true") } else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "check", arg[2]); kit.Right(cid) { @@ -668,224 +615,15 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } } }) - default: + + m.Log("right", "bench: %s sessid: %s user: %s com: %v result: %v", + m.Option("bench"), m.Option("sessid"), m.Option("username"), arg[2:], m.Result(0)) + default: // 读写数据 m.Cmdx("aaa.auth", bid, arg) } return }}, - "login": &ctx.Command{Name: "login [sessid]|[username password]", - Form: map[string]int{"ip": 1, "openid": 1, "cert": 1, "pub": 1, "key": 1}, - Help: []string{"会话管理", "sessid: 令牌", "username: 账号", "password: 密码", - "ip: 主机地址", "openid: 微信登录", "cert: 证书", "pub: 公钥", "key: 私钥"}, - Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if _, ok := c.Server.(*AAA); m.Assert(ok) { - method := "" - for _, v := range []string{"ip", "openid", "cert", "pub", "key"} { - if m.Has(v) { - method = v - } - } - if method != "" { - c.Travel(m, func(m *ctx.Message, n int) bool { - if n > 0 && m.Cap("method") == method { - switch method { - case "ip", "openid": - if m.Cap("stream") == m.Option(method) { - m.Cap("expire_time", fmt.Sprintf("%d", time.Now().Unix()+int64(m.Confi("expire")))) - m.Echo(m.Cap("sessid")) - return false - } - case "cert", "pub", "key": - if m.Cap("stream") == Password(m.Option(method)) { - m.Cap("expire_time", fmt.Sprintf("%d", time.Now().Unix()+int64(m.Confi("expire")))) - m.Echo(m.Cap("sessid")) - return false - } - } - } - return false - }) - - if m.Results(0) { - return - } - - m.Start(fmt.Sprintf("user%d", m.Capi("nuser", 1)), "用户登录", method, m.Option(method)) - m.Echo(m.Cap("sessid")) - return - } - - switch len(arg) { - case 2: - c.Travel(m, func(m *ctx.Message, n int) bool { - if n > 0 && m.Cap("method") == "password" && m.Cap("stream") == arg[0] { - m.Assert(m.Cap("password") == Password(arg[1])) - m.Cap("expire_time", fmt.Sprintf("%d", time.Now().Unix()+int64(m.Confi("expire")))) - m.Echo(m.Cap("sessid")) - return false - } - return false - }) - - if m.Results(0) { - m.Append("sessid", m.Result(0)) - return - } - if arg[0] == "" { - return - } - - name := "" - switch arg[0] { - case "root", "void": - name = arg[0] - default: - name = fmt.Sprintf("user%d", m.Capi("nuser", 1)) - } - - m.Start(name, "密码登录", "password", arg[0]) - m.Cap("password", "password", Password(arg[1]), "密码登录") - m.Append("sessid", m.Cap("sessid")) - m.Echo(m.Cap("sessid")) - return - case 1: - m.Sess("login", nil) - c.Travel(m, func(m *ctx.Message, n int) bool { - if n > 0 && m.Cap("sessid") == arg[0] { - if int64(m.Capi("expire_time")) > time.Now().Unix() { - m.Sess("login", m.Target().Message()) - m.Append("login_time", time.Unix(int64(m.Capi("login_time")), 0).Format(m.Conf("time_format"))) - m.Append("expire_time", time.Unix(int64(m.Capi("expire_time")), 0).Format(m.Conf("time_format"))) - m.Echo(m.Cap("stream")) - } else { - m.Target().Close(m) - } - return false - } - return true - }) - case 0: - c.Travel(m, func(m *ctx.Message, n int) bool { - if n > 0 { - m.Add("append", "method", m.Cap("method")) - m.Add("append", "stream", m.Cap("stream")) - } - return false - }) - m.Table() - } - } - return - }}, - "userinfo": &ctx.Command{Name: "userinfo sessid", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - c.Travel(m, func(m *ctx.Message, n int) bool { - if m.Cap("sessid") == arg[0] { - m.Append("method", m.Cap("method")) - m.Append("stream", m.Cap("stream")) - m.Append("sessid", m.Cap("sessid")) - m.Append("login_time", m.Cap("login_time")) - m.Append("expire_time", m.Cap("expire_time")) - } - return false - }) - m.Table() - return - }}, - "right": &ctx.Command{Name: "right [user [check|owner|share group [order] [add|del]]]", Form: map[string]int{"from": 1}, Help: "权限管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - c.Travel(m, func(m *ctx.Message, n int) bool { - if n == 0 { - return true - } - if len(arg) == 0 { - m.Add("append", "user", m.Cap("stream")) - m.Add("append", "right", m.Confv("right")) - return true - } - if m.Cap("stream") == arg[0] { - if len(arg) == 1 { //查看所有权 - for k, v := range m.Confv("right").(map[string]interface{}) { - for order, right := range v.(map[string]interface{}) { - m.Add("append", "group", k) - m.Add("append", "order", order) - m.Add("append", "right", right) - } - } - return true - } - if arg[1] == "check" { //权限检查 - if from := m.Confv("right", []interface{}{"right", "role"}); from != nil && from.(string) == "root" { - m.Echo("root") - } - if len(arg) == 2 { - return false - } - if from := m.Confv("right", []interface{}{arg[2], "right", "role"}); from != nil && from.(string) == "owner" { - m.Echo("owner") - } - if len(arg) == 3 { - return false - } - if from := m.Confv("right", []interface{}{arg[2], arg[3], "right", "role"}); from != nil && from.(string) == "share" { - m.Echo("share") - } - return false - } - if len(arg) == 2 { //分配人事权 - if m.Option("from") != "root" { - return false - } - switch arg[1] { - case "add": - m.Confv("right", []interface{}{"right", "role"}, "root") - m.Confv("right", []interface{}{"right", "from"}, m.Option("from")) - case "del": - m.Confv("right", []interface{}{"right", "role"}, "") - } - return true - } - if len(arg) == 3 { //查看使用权 - for k, v := range m.Confv("right", arg[2]).(map[string]interface{}) { - for order, right := range v.(map[string]interface{}) { - m.Add("append", "order", k) - m.Add("append", "right", order) - m.Add("append", "detail", right) - } - } - return true - } - switch arg[1] { - case "owner": //分配所有权 - if m.Cmd("right", m.Option("from"), "check").Result(0) == "" { - return false - } - switch arg[3] { - case "add": - m.Confv("right", []interface{}{arg[2], "right", "role"}, "owner") - m.Confv("right", []interface{}{arg[2], "right", "from"}, m.Option("from")) - case "del": - m.Confv("right", []interface{}{arg[2], "right", "role"}, "") - } - case "share": //分配使用权 - if m.Cmd("right", m.Option("from"), "check", arg[2]).Result(0) == "" { - return false - } - switch arg[4] { - case "add": - m.Confv("right", []interface{}{arg[2], arg[3], "right", "role"}, "share") - m.Confv("right", []interface{}{arg[2], arg[3], "right", "from"}, m.Option("from")) - case "del": - m.Confv("right", []interface{}{arg[2], arg[3], "right", "role"}, "") - } - } - return false - } - return false - }) - m.Table() - return - }}, - "rsa": &ctx.Command{Name: "rsa gen|sign|verify|encrypt|decrypt|cert", Help: []string{"gen: 生成密钥, sgin: 私钥签名, verify: 公钥验签, encrypt: 公钥加密, decrypt: 私钥解密", "密钥: rsa gen [keyfile [pubfile [certfile]]]", diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 281aeb68..bbd52359 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -139,7 +139,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } // 解析脚本文件 - if p := m.Cmdx("nfs.path", arg[0]); p != "" { + if p := m.Cmdx("nfs.path", arg[0]); p != "" && strings.Contains(p, ".") { arg[0] = p switch path.Ext(p) { case "": diff --git a/src/contexts/ctx/ctx_init.go b/src/contexts/ctx/ctx_init.go index 48a38b0b..fadf067d 100644 --- a/src/contexts/ctx/ctx_init.go +++ b/src/contexts/ctx/ctx_init.go @@ -72,7 +72,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, "debug": &Config{Name: "debug(on/off)", Value: "on", Help: "调试模式,on:打印,off:不打印)"}, "search_method": &Config{Name: "search_method(find/search)", Value: "search", Help: "搜索方法, find: 模块名精确匹配, search: 模块名或帮助信息模糊匹配"}, - "search_choice": &Config{Name: "search_choice(first/last/rand/magic)", Value: "magic", Help: "搜索匹配, first: 匹配第一个模块, last: 匹配最后一个模块, rand: 随机选择, magic: 加权选择"}, + "search_choice": &Config{Name: "search_choice(first/last/rand/magics)", Value: "magics", Help: "搜索匹配, first: 匹配第一个模块, last: 匹配最后一个模块, rand: 随机选择, magics: 加权选择"}, "search_action": &Config{Name: "search_action(list/switch)", Value: "switch", Help: "搜索操作, list: 输出模块列表, switch: 模块切换"}, "search_root": &Config{Name: "search_root(true/false)", Value: "true", Help: "搜索起点, true: 根模块, false: 当前模块"}, @@ -360,6 +360,20 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, m.Sort("key", "string").Table() return }}, + "magic": &Command{Name: "magic", Help: "随机组员", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { + switch len(arg) { + case 0: + m.Optionv("magic", m.Magic("bench", "")) + case 1: + m.Optionv("magic", m.Magic(arg[0], "")) + case 2: + m.Optionv("magic", m.Magic(arg[0], arg[1])) + case 3: + m.Optionv("magic", m.Magic(arg[0], arg[1], arg[2])) + } + m.Cmdy("ctx.trans", "magic") + return + }}, "result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { msg := m.message if len(arg) == 0 { @@ -481,7 +495,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, }}, "context": &Command{Name: "context [find|search] [root|back|home] [first|last|rand|magic] [module] [cmd|switch|list|spawn|start|close]", - Help: "查找并操作模块;\n查找方法, find: 精确查找, search: 模糊搜索;\n查找起点, root: 根模块, back: 父模块, home: 本模块;\n过滤结果, first: 取第一个, last: 取最后一个, rand: 随机选择, magic: 智能选择;\n操作方法, cmd: 执行命令, switch: 切换为当前, list: 查看所有子模块, spwan: 创建子模块并初始化, start: 启动模块, close: 结束模块", + Help: "查找并操作模块;\n查找方法, find: 精确查找, search: 模糊搜索;\n查找起点, root: 根模块, back: 父模块, home: 本模块;\n过滤结果, first: 取第一个, last: 取最后一个, rand: 随机选择, magics: 智能选择;\n操作方法, cmd: 执行命令, switch: 切换为当前, list: 查看所有子模块, spwan: 创建子模块并初始化, start: 启动模块, close: 结束模块", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { if len(arg) == 1 && arg[0] == "~" && m.target.context != nil { m.target = m.target.context @@ -534,7 +548,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, ms, arg = append(ms, msg[len(msg)-1]), arg[2:] case "rand": ms, arg = append(ms, msg[rand.Intn(len(msg))]), arg[2:] - case "magic": + case "magics": ms, arg = append(ms, msg...), arg[2:] default: ms, arg = append(ms, msg[0]), arg[1:] @@ -780,6 +794,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, }}, "config": &Command{Name: "config [all] [export key..] [save|load file key...] [list|map arg...] [create map|list|string key name help] [delete key]", Help: "配置管理, export: 导出配置, save: 保存配置到文件, load: 从文件加载配置, create: 创建配置, delete: 删除配置", + Form: map[string]int{"format": 1}, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { if len(arg) > 2 && arg[2] == "list" { chain := strings.Split(arg[1], ".") @@ -942,157 +957,164 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, return }}, - "trans": &Command{Name: "trans option [type|data|json] limit 10 [index...]", Help: "数据转换", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - value, arg := m.Optionv(arg[0]), arg[1:] - if v, ok := value.(string); ok { - json.Unmarshal([]byte(v), &value) - } - - view := "data" - if len(arg) > 0 { - switch arg[0] { - case "type", "data", "json": - view, arg = arg[0], arg[1:] + "trans": &Command{Name: "trans option [type|data|json] limit 10 [index...]", Help: "数据转换", + Form: map[string]int{"format": 1}, + Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { + value, arg := m.Optionv(arg[0]), arg[1:] + if v, ok := value.(string); ok { + json.Unmarshal([]byte(v), &value) } - } - limit := kit.Int(kit.Select(m.Conf("page_limit"), m.Option("limit"))) - if len(arg) > 0 && arg[0] == "limit" { - limit, arg = kit.Int(arg[1]), arg[2:] - } - m.Log("fuck", "trans limt %v", limit) + view := "data" + if len(arg) > 0 { + switch arg[0] { + case "type", "data", "json": + view, arg = arg[0], arg[1:] + } + } - chain := strings.Join(arg, ".") - if chain != "" { - value = kit.Chain(value, chain) - } + limit := kit.Int(kit.Select(m.Conf("page_limit"), m.Option("limit"))) + if len(arg) > 0 && arg[0] == "limit" { + limit, arg = kit.Int(arg[1]), arg[2:] + } - switch view { - case "type": // 查看数据类型 - switch value := value.(type) { + chain := strings.Join(arg, ".") + if chain != "" { + value = kit.Chain(value, chain) + } + + switch view { + case "type": // 查看数据类型 + switch value := value.(type) { + case map[string]interface{}: + for k, v := range value { + m.Add("append", "key", k) + m.Add("append", "type", fmt.Sprintf("%T", v)) + } + m.Sort("key", "str").Table() + case []interface{}: + for k, v := range value { + m.Add("append", "key", k) + m.Add("append", "type", fmt.Sprintf("%T", v)) + } + m.Sort("key", "int").Table() + case nil: + default: + m.Add("append", "key", chain) + m.Add("append", "type", fmt.Sprintf("%T", value)) + m.Sort("key", "str").Table() + } + return + case "data": + case "json": // 查看文本数据 + b, e := json.MarshalIndent(value, "", " ") + m.Assert(e) + m.Echo(string(b)) + return nil + } + + switch val := value.(type) { case map[string]interface{}: - for k, v := range value { + for k, v := range val { + if m.Option("format") == "object" { + m.Add("append", k, v) + continue + } + m.Add("append", "key", k) - m.Add("append", "type", fmt.Sprintf("%T", v)) + switch val := v.(type) { + case nil: + m.Add("append", "value", "") + case string: + m.Add("append", "value", val) + case float64: + m.Add("append", "value", fmt.Sprintf("%d", int(val))) + default: + b, _ := json.Marshal(val) + m.Add("append", "value", fmt.Sprintf("%s", string(b))) + } + } + m.Table() + // m.Sort("key", "str").Table() + case map[string]string: + for k, v := range val { + m.Add("append", "key", k) + m.Add("append", "value", v) } m.Sort("key", "str").Table() case []interface{}: - for k, v := range value { - m.Add("append", "key", k) - m.Add("append", "type", fmt.Sprintf("%T", v)) - } - m.Sort("key", "int").Table() - case nil: - default: - m.Add("append", "key", chain) - m.Add("append", "type", fmt.Sprintf("%T", value)) - m.Sort("key", "str").Table() - } - return - case "data": - case "json": // 查看文本数据 - b, e := json.MarshalIndent(value, "", " ") - m.Assert(e) - m.Echo(string(b)) - return nil - } - - switch val := value.(type) { - case map[string]interface{}: - for k, v := range val { - m.Add("append", "key", k) - switch val := v.(type) { - case nil: - m.Add("append", "value", "") - case string: - m.Add("append", "value", val) - case float64: - m.Add("append", "value", fmt.Sprintf("%d", int(val))) - default: - b, _ := json.Marshal(val) - m.Add("append", "value", fmt.Sprintf("%s", string(b))) - } - } - m.Sort("key", "str").Table() - case map[string]string: - for k, v := range val { - m.Add("append", "key", k) - m.Add("append", "value", v) - } - m.Sort("key", "str").Table() - case []interface{}: - fields := map[string]int{} - for i, v := range val { - if i >= limit { - break - } - switch val := v.(type) { - case map[string]interface{}: - for k, _ := range val { - fields[k]++ - } - } - } - - if len(fields) > 0 { + fields := map[string]int{} for i, v := range val { if i >= limit { break } switch val := v.(type) { case map[string]interface{}: - for k, _ := range fields { - switch value := val[k].(type) { - case nil: - m.Add("append", k, "") - case string: - m.Add("append", k, value) - case float64: - m.Add("append", k, fmt.Sprintf("%d", int(value))) - default: - b, _ := json.Marshal(value) - m.Add("append", k, fmt.Sprintf("%v", string(b))) - } + for k, _ := range val { + fields[k]++ } } } - } else { - for i, v := range val { - switch val := v.(type) { - case nil: - m.Add("append", "index", i) - m.Add("append", "value", "") - case string: - m.Add("append", "index", i) - m.Add("append", "value", val) - case float64: - m.Add("append", "index", i) - m.Add("append", "value", fmt.Sprintf("%v", int(val))) - default: - m.Add("append", "index", i) - b, _ := json.Marshal(val) - m.Add("append", "value", fmt.Sprintf("%v", string(b))) + + if len(fields) > 0 { + for i, v := range val { + if i >= limit { + break + } + switch val := v.(type) { + case map[string]interface{}: + for k, _ := range fields { + switch value := val[k].(type) { + case nil: + m.Add("append", k, "") + case string: + m.Add("append", k, value) + case float64: + m.Add("append", k, fmt.Sprintf("%d", int(value))) + default: + b, _ := json.Marshal(value) + m.Add("append", k, fmt.Sprintf("%v", string(b))) + } + } + } + } + } else { + for i, v := range val { + switch val := v.(type) { + case nil: + m.Add("append", "index", i) + m.Add("append", "value", "") + case string: + m.Add("append", "index", i) + m.Add("append", "value", val) + case float64: + m.Add("append", "index", i) + m.Add("append", "value", fmt.Sprintf("%v", int(val))) + default: + m.Add("append", "index", i) + b, _ := json.Marshal(val) + m.Add("append", "value", fmt.Sprintf("%v", string(b))) + } } } + m.Table() + case []string: + for i, v := range val { + m.Add("append", "index", i) + m.Add("append", "value", v) + } + m.Table() + case string: + m.Echo("%s", val) + case float64: + m.Echo("%d", int(val)) + case nil: + default: + b, _ := json.Marshal(val) + m.Echo("%s", string(b)) } - m.Table() - case []string: - for i, v := range val { - m.Add("append", "index", i) - m.Add("append", "value", v) - } - m.Table() - case string: - m.Echo("%s", val) - case float64: - m.Echo("%d", int(val)) - case nil: - default: - b, _ := json.Marshal(val) - m.Echo("%s", string(b)) - } - return - }}, + return + }}, "select": &Command{Name: "select key value field", Form: map[string]int{"eq": 2, "parse": 2, "hide": -1, "fields": -1, "group": 1, "order": 2, "limit": 1, "offset": 1, "format": -1, "trans_map": -1, "vertical": 0}, Help: "选取数据", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { diff --git a/src/contexts/ctx/ctx_type.go b/src/contexts/ctx/ctx_type.go index e7ca7b5f..ef7104ec 100644 --- a/src/contexts/ctx/ctx_type.go +++ b/src/contexts/ctx/ctx_type.go @@ -598,6 +598,9 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:]) } case "option", "append": + if msg.Meta == nil { + msg.Meta = map[string][]string{} + } if msg.Meta[meta] == nil { break } @@ -762,6 +765,35 @@ func (m *Message) Optionx(key string, arg ...string) interface{} { } return value } +func (m *Message) Magic(begin string, chain interface{}, args ...interface{}) interface{} { + auth := []string{"bench", "session", "username", "role", "componet", "command"} + key := []string{"bench", "sessid", "username", "role", "componet", "command"} + aaa := m.Sess("aaa", false) + for i, v := range auth { + if v == begin { + data := aaa.Confv("auth", []string{m.Option(key[i]), "data"}) + if kit.Format(chain) == "" { + return data + } + + if len(args) > 0 { + value := kit.Chain(data, chain, args[0]) + aaa.Conf("auth", []string{m.Option(key[i]), "data"}, value) + return value + } + + value := kit.Chain(data, chain) + if value != nil { + return value + } + + if i < len(auth)-1 { + begin = auth[i+1] + } + } + } + return nil +} func (m *Message) Append(key string, arg ...interface{}) string { if len(arg) > 0 { m.Insert(key, 0, arg...) diff --git a/src/contexts/log/log.go b/src/contexts/log/log.go index 12c21336..298c3578 100644 --- a/src/contexts/log/log.go +++ b/src/contexts/log/log.go @@ -128,6 +128,8 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心", "call": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}}, "back": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}}, + "right": map[string]interface{}{"value": map[string]interface{}{"file": "right.log", "meta": []interface{}{"time", "ship"}}}, + "bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}}, "begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}}, "start": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}}, diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 8a44eb6c..97f2277b 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -878,10 +878,14 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { nfs.Configs["prompt"] = &ctx.Config{Value: ""} if nfs.in = m.Optionv("in").(*os.File); m.Has("out") { - if nfs.out = m.Optionv("out").(*os.File); m.Cap("goos") != "windows" { + if nfs.out = m.Optionv("out").(*os.File); m.Cap("goos") != "windows" && m.Confs("term", "enable") { nfs.Term(m, "init") defer nfs.Term(m, "exit") } + what := make(chan bool) + if m.Confs("term", "loop") { + <-what + } } line, bio := "", bufio.NewScanner(nfs) @@ -922,7 +926,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { } m.Cap("stream", m.Option("ms_source")) - nfs.io = m.Optionv("io").(io.ReadWriter) + nfs.io, _ = m.Optionv("io").(io.ReadWriter) nfs.send = make(chan *ctx.Message, 10) nfs.echo = make(chan *ctx.Message, 10) nfs.hand = map[int]*ctx.Message{} @@ -1023,6 +1027,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", }, Configs: map[string]*ctx.Config{ "term": &ctx.Config{Name: "term", Value: map[string]interface{}{ + "enable": 1, "loop": 0, "width": 80, "height": "24", "left": 0, "top": 0, "right": 80, "bottom": 24, @@ -1510,6 +1515,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", "remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{ m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message { + if sub.Options("hostport") { + return sub + } sub.Sess("ms_source", sub) sub.Sess("ms_target", m.Source()) sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件") diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index 70968dc8..c11dd958 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -39,82 +39,93 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", }, Configs: map[string]*ctx.Config{ "host": &ctx.Config{Name: "host", Value: map[string]interface{}{}, Help: "主机信息"}, + "hostport": &ctx.Config{Name: "hostport", Value: "", Help: "主机域名"}, "hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机域名"}, "current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"}, "timer": &ctx.Config{Name: "timer", Value: "", Help: "当前主机"}, }, Commands: map[string]*ctx.Command{ - "remote": &ctx.Command{Name: "remote listen|dial args...", Help: "远程连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { + "remote": &ctx.Command{Name: "remote listen|dial args...", Help: "远程连接", Form: map[string]int{"right": 1, "hostname": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) == 0 { // 查看主机 m.Cmdy("ctx.config", "host") return } switch arg[0] { - case "redial": + case "redial": // 断线重连 if !m.Caps("hostname") { m.Cmdx("remote", "dial", arg[1:]) } case "listen", "dial": m.Call(func(nfs *ctx.Message) *ctx.Message { - if arg[0] == "dial" { - if m.Confs("timer") { + if arg[0] == "listen" && nfs.Options("hostport") { // 监听端口 + m.Conf("hostport", nfs.Option("hostport")) + + } else if arg[0] == "dial" { + if m.Confs("timer") { // 断线重连 m.Conf("timer", m.Cmdx("cli.timer", "delete", m.Conf("timer"))) } - m.Spawn(nfs.Target()).Call(func(cmd *ctx.Message) *ctx.Message { - m.Cap("stream", nfs.Format("target")) - m.Cap("hostname", cmd.Result(0)) - m.Confv("host", cmd.Result(1), map[string]interface{}{ + m.Spawn(nfs.Target()).Call(func(host *ctx.Message) *ctx.Message { + m.Confv("host", host.Result(1), map[string]interface{}{ // 添加主机 "module": nfs.Format("target"), "create_time": m.Time(), "access_time": m.Time(), + "username": m.Option("right"), + "cm_target": "ctx.web.code", }) + + m.Cap("stream", nfs.Format("target")) + m.Cap("hostname", host.Result(0)) if !m.Confs("current") { - m.Conf("current", cmd.Result(1)) + m.Conf("current", host.Result(1)) } - nfs.Free(func(nfs *ctx.Message) bool { + nfs.Free(func(nfs *ctx.Message) bool { // 连接中断 m.Conf("timer", m.Cmdx("cli.timer", "repeat", "10s", "context", "ssh", "remote", "redial", arg[1:])) - m.Log("info", "delete host %s", cmd.Result(1)) - delete(m.Confm("host"), cmd.Result(1)) + m.Log("info", "delete host %s", host.Result(1)) + delete(m.Confm("host"), host.Result(1)) m.Cap("hostname", "") m.Cap("stream", "") return true }) return nil - }, "send", "recv", "add", m.Conf("hostname")) + }, "send", "recv", "add", m.Confx("hostname")) } return nil }, "nfs.remote", arg) - case "recv": switch arg[1] { case "add": - if host := m.Confm("host", arg[2]); host == nil { + if host := m.Confm("host", arg[2]); host == nil { // 添加主机 m.Confv("host", arg[2], map[string]interface{}{ "module": m.Format("source"), "create_time": m.Time(), "access_time": m.Time(), + "username": m.Option("right"), + "cm_target": "ctx.web.code", }) - } else if len(arg) > 3 && arg[3] == kit.Format(host["token"]) { + } else if len(arg) > 3 && arg[3] == kit.Format(host["token"]) { // 断线重连 host["access_time"] = m.Time() host["module"] = m.Format("source") - } else { + } else { // 域名冲突 arg[2] = fmt.Sprintf("%s_%d", arg[2], m.Capi("nhost", 1)) m.Confv("host", arg[2], map[string]interface{}{ "module": m.Format("source"), "create_time": m.Time(), "access_time": m.Time(), + "username": m.Option("right"), + "cm_target": "ctx.web.code", }) } + if !m.Confs("current") { m.Conf("current", arg[2]) } m.Echo(arg[2]).Echo(m.Cap("hostname")).Back(m) - m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool { + m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool { // 断线清理 m.Log("info", "delete host %s", arg[2]) delete(m.Confm("host"), arg[2]) return true @@ -122,44 +133,58 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", } default: - names := strings.SplitN(arg[0], ".", 2) + names, arg := strings.SplitN(arg[0], ".", 2), arg[1:] + if names[0] == "" { // 本地执行 host := m.Confm("host", m.Option("hostname")) - m.Option("current_ctx", kit.Format(host["cm_target"])) + user := kit.Format(kit.Chain(host, "username")) - msg := m.Find(kit.Format(host["cm_target"])).Cmd(arg[1:]) - m.Copy(msg, "append").Copy(msg, "result") - host["cm_target"] = msg.Cap("module") + sessid := m.Cmd("aaa.user", user, "ssh").Append("meta") + if sessid == "" { // 创建会话 + sessid = m.Cmdx("aaa.sess", "ssh", "ip", "what") + m.Cmd("aaa.sess", sessid, user, "ppid", "what") + } + bench := m.Cmd("aaa.sess", sessid, "bench").Append("meta") + if bench == "" { // 创建空间 + bench = m.Cmdx("aaa.work", sessid, "ssh") + } + + if m.Cmds("aaa.work", bench, "right", user, "remote", arg[0]) { // 执行命令 + msg := m.Find(m.Option("current_ctx", kit.Format(host["cm_target"]))).Cmd(arg).CopyTo(m) + host["cm_target"] = msg.Cap("module") + } else { + m.Echo("no right %s %s", "remote", arg[0]) + } + + // 返回结果 m.Back(m) return } - m.Option("hostname", m.Cap("hostname")) - sync := !m.Options("remote_code") //同步或异步 - if arg[1] == "async" { - sync, arg = false, arg[2:] - } else if arg[1] == "sync" { - sync, arg = true, arg[2:] - } else { - arg = arg[1:] + //同步或异步 + sync := !m.Options("remote_code") + switch arg[0] { + case "async", "sync": + sync, arg = arg[0] == "sync", arg[1:] } rest := kit.Select("", names, 1) - if names[0] == "*" { + m.Option("hostname", m.Cap("hostname")) + + if names[0] == "*" { // 广播命令 m.Confm("host", func(name string, host map[string]interface{}) { m.Find(kit.Format(host["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { return m.Copy(sub, "append").Copy(sub, "result") }, "send", "", arg) }) - } else if m.Confm("host", names[0], func(host map[string]interface{}) { + } else if m.Confm("host", names[0], func(host map[string]interface{}) { // 单播命令 m.Find(kit.Format(host["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { return m.Copy(sub, "append").Copy(sub, "result") }, "send", rest, arg) - m.Log("fuck", "m %v", m.Meta) - }) == nil { + }) == nil { // 回溯命令 m.Find(m.Cap("stream"), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { return m.Copy(sub, "append").Copy(sub, "result") }, "send", strings.Join(names, "."), arg) diff --git a/src/contexts/tcp/tcp.go b/src/contexts/tcp/tcp.go index 2b53d04b..83415382 100644 --- a/src/contexts/tcp/tcp.go +++ b/src/contexts/tcp/tcp.go @@ -55,6 +55,18 @@ func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { return tcp } func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { + if arg[1] == "consul" { + arg[1] = m.Cmdx("web.get", "", arg[2], "temp", "hostport.0") + if arg[1] == "" { + return true + } + for i := 2; i < len(arg)-1; i++ { + arg[i] = arg[i+1] + } + if len(arg) > 2 { + arg = arg[:len(arg)-1] + } + } m.Cap("address", m.Confx("address", arg, 1)) m.Cap("security", m.Confx("security", arg, 2)) m.Cap("protocol", m.Confx("protocol", arg, 3)) @@ -115,6 +127,10 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { m.Log("info", "%d listen %v", m.Capi("nlisten"), m.Cap("stream", fmt.Sprintf("%s", tcp.Addr()))) + + addr := strings.Split(tcp.Addr().String(), ":") + m.Log("fuck", "what %v", addr) + m.Back(m.Spawn(m.Source()).Add("option", "hostport", fmt.Sprintf("%s:%s", m.Cmd("tcp.ifconfig", "eth0").Append("ip"), addr[len(addr)-1]))) } for { @@ -151,6 +167,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心", "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}, }, Configs: map[string]*ctx.Config{ + "": &ctx.Config{Name: "address", Value: ":9090", Help: "网络地址"}, "address": &ctx.Config{Name: "address", Value: ":9090", Help: "网络地址"}, "security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"}, "protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"}, @@ -185,19 +202,22 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心", } return }}, - "ifconfig": &ctx.Command{Name: "ifconfig", Help: "网络配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "ifconfig": &ctx.Command{Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if ifs, e := net.Interfaces(); m.Assert(e) { for _, v := range ifs { if ips, e := v.Addrs(); m.Assert(e) { for _, x := range ips { - ip := x.String() + ip := strings.Split(x.String(), "/") - if !strings.Contains(ip, ":") && len(ip) > 0 && len(v.HardwareAddr) > 0 { + if !strings.Contains(ip[0], ":") && len(ip) > 0 && len(v.HardwareAddr) > 0 { + if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) { + continue + } m.Add("append", "index", v.Index) m.Add("append", "name", v.Name) m.Add("append", "hard", v.HardwareAddr) - m.Add("append", "ip", ip) + m.Add("append", "ip", ip[0]) } } } diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index b94d160f..1d27d139 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -89,6 +89,9 @@ func Merge(m *ctx.Message, client map[string]interface{}, uri string, arg ...str } func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) bool { + if msg.Confs("skip_login", msg.Option("path")) { + return true + } if msg.Confs("login", "cas_url") && !msg.Confs("login", "skip_cas") { if !cas.IsAuthenticated(r) { r.URL, _ = r.URL.Parse(r.Header.Get("index_url")) @@ -103,11 +106,13 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) } if msg.Options("ticket") { + msg.Log("fuck", "what %v", msg.Meta) msg.Option("uuid", msg.Option(msg.Conf("login", "cas_uuid"))) msg.Option("username", cas.Username(r)) if lark := msg.Find("web.chat.lark"); lark != nil { msg.Option("username", lark.Cmdx("user", msg.Option("email"), "id")) } + msg.Log("fuck", "what %v", msg.Meta) http.SetCookie(w, &http.Cookie{Name: "sessid", Value: msg.Cmdx("web.session", "login", "uuid"), Path: "/"}) http.Redirect(w, r, merge(msg, r.Header.Get("index_url"), "ticket", ""), http.StatusTemporaryRedirect) @@ -121,6 +126,9 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) } return false } + if !msg.Options("current_ctx") { + http.SetCookie(w, &http.Cookie{Name: "current_ctx", Value: msg.Option("current_ctx", "mdb"), Path: "/"}) + } return true } func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { @@ -499,7 +507,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } - m.Log("info", "%s %s", method, uri) req, e := http.NewRequest(method, uri, body) m.Assert(e) m.Log("info", "%s %s", req.Method, req.URL) @@ -789,7 +796,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", switch arg[0] { case "login": - if len(arg) == 1 { + if len(arg) == 1 { // 查询用户 m.Echo(m.Cmd("aaa.sess", sessid, "username").Append("meta")) break } @@ -797,25 +804,26 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", if username == "" || !m.Options(arg[1]) { break } - if sessid == "" || !m.Cmds("aaa.sess", sessid) { + if sessid == "" || !m.Cmds("aaa.sess", sessid) { // 创建会话 sessid = m.Cmdx("aaa.sess", "web", "ip", m.Option("remote_ip")) } - if m.Cmds("aaa.sess", sessid, m.Option("username"), arg[1], m.Option(arg[1])) { + if m.Cmds("aaa.sess", sessid, m.Option("username"), arg[1], m.Option(arg[1])) { // 用户登录 m.Echo(sessid) } case "bench": - if len(arg) == 1 { + if len(arg) == 1 { // 创建空间 bench := m.Option("bench") - if bench == "" || !m.Cmds("aaa.work", bench) { // 创建空间 - bench = m.Cmdx("aaa.work", sessid, "create", "web") + if bench == "" || !m.Cmds("aaa.work", bench) { + bench = m.Cmdx("aaa.work", sessid, "web") } m.Echo(bench) break } + // 添加数据 m.Cmd("aaa.work", arg[1:]) - case "check": + case "check": // 检查权限 m.Echo(m.Cmdx("aaa.work", arg[1], "right", arg[2:])) } return @@ -930,6 +938,13 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } + if m.Options("sessid") { + m.Magic("session", "what", 1) + m.Log("fuck", "what %v", m.Magic("bench", "what")) + m.Magic("bench", "what", 2) + m.Log("fuck", "what %v", m.Magic("bench", "what")) + } + // 执行命令 if order != "" || kit.Right(val["pre_run"]) { if list := m.Confv("auth", []string{m.Option("bench"), "data", "action", msg.Option("componet_name"), "cmd"}); list != nil && order == "" { diff --git a/src/examples/code/code.go b/src/examples/code/code.go index 0d875fc5..a5b566b6 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -5,12 +5,17 @@ import ( "contexts/web" "fmt" "net/http" + "os" "strconv" + "time" ) var Index = &ctx.Context{Name: "code", Help: "代码中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ + "skip_login": &ctx.Config{Name: "skip_login", Value: map[string]interface{}{ + "/consul": "true", + }, Help: "免登录"}, "counter": &ctx.Config{Name: "counter", Value: map[string]interface{}{ "nopen": "0", "nsave": "0", }, Help: "counter"}, @@ -209,9 +214,10 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", }, Help: "组件列表"}, "upgrade": &ctx.Config{Name: "upgrade", Value: map[string]interface{}{ "file": map[string]interface{}{ - "init_shy": "etc/init0.shy", - "exit_shy": "etc/exit.shy", - "bench": "bin/bench", + "init_shy": "etc/init.shy", + "common_shy": "etc/common.shy", + "exit_shy": "etc/exit.shy", + "bench": "bin/bench.new", }, }, Help: "日志地址"}, }, @@ -250,21 +256,49 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", return }}, "upgrade": &ctx.Command{Name: "upgrade system|script", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) > 0 && arg[0] == "system" { + if len(arg) == 0 { + m.Cmdy("ctx.config", "upgrade", "file") + return + } + + if arg[0] == "system" { m.Cmd("cli.source", m.Conf("exit.shy")) m.Confm("upgrade", "file", func(key string, value string) { m.Cmd("web.get", "dev", fmt.Sprintf("code/upgrade/%s", key), "save", value) }) - m.Cmd("cli.system", "chmod", "u+x", "bin/bench") - // os.Exit(1) + m.Cmd("cli.system", "chmod", "u+x", "bin/bench.new") + m.Cmd("cli.system", "mv", "bin/bench", fmt.Sprintf("bin/bench_%s", m.Time("20060102_150405"))) + m.Cmd("cli.system", "mv", "bin/bench.new", "bin/bench") + go func() { + time.Sleep(time.Second * 3) + os.Exit(1) + }() + return + } + + if file := m.Conf("upgrade", []string{"file", arg[0]}); file != "" { + m.Cmd("web.get", "dev", fmt.Sprintf("code/upgrade/%s", arg[0]), "save", file) + if arg[0] == "bench" { + m.Cmd("cli.system", "chmod", "u+x", "bin/bench.new") + m.Cmd("cli.system", "mv", "bin/bench", fmt.Sprintf("bin/bench_%s", m.Time("20060102_150405"))) + m.Cmd("cli.system", "mv", "bin/bench.new", "bin/bench") + } + go func() { + time.Sleep(time.Second * 3) + os.Exit(1) + }() return } m.Cmdy("web.get", "dev", fmt.Sprintf("code/upgrade/script/%s", arg[0]), "save", fmt.Sprintf("usr/script/%s", arg[0]), arg[1:]) return }}, + "/consul": &ctx.Command{Name: "/consul", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + m.Append("hostport", m.Cmdx("ssh.config", "hostport")) + return + }}, }, } diff --git a/src/toolkit/kit.go b/src/toolkit/kit.go index 8202371f..c0c9884e 100644 --- a/src/toolkit/kit.go +++ b/src/toolkit/kit.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "io" "strconv" "strings" @@ -37,17 +38,46 @@ func Int(arg ...interface{}) int { switch val := v.(type) { case int: result += val - case bool: - if val { - result += 1 - } + case int8: + result += int(val) + case int16: + result += int(val) + // case int32: + // result += int(val) + case int64: + result += int(val) + // case uint8: + // result += int(val) + case uint16: + result += int(val) + case uint32: + result += int(val) + case uint64: + result += int(val) + case float64: + result += int(val) + case byte: // uint8 + result += int(val) + case rune: // int32 + result += int(val) case string: if i, e := strconv.Atoi(val); e == nil { result += i } + case bool: + if val { + result += 1 + } case time.Time: result += int(val.Unix()) - default: + case []string: + result += len(val) + case map[string]string: + result += len(val) + case []interface{}: + result += len(val) + case map[string]interface{}: + result += len(val) } } return result @@ -64,12 +94,19 @@ func Right(arg ...interface{}) bool { switch val { case "", "0", "false", "off", "no", "error: ": result = result || false - break default: result = result || true } case error: result = result || false + case []string: + result = result || len(val) > 0 + case map[string]string: + result = result || len(val) > 0 + case []interface{}: + result = result || len(val) > 0 + case map[string]interface{}: + result = result || len(val) > 0 default: result = result || val != nil } @@ -82,28 +119,28 @@ func Format(arg ...interface{}) string { switch val := v.(type) { case nil: result = result[:0] - case uint, uint8, uint16, uint32, uint64: - result = append(result, fmt.Sprintf("%d", val)) case int, int8, int16, int32, int64: result = append(result, fmt.Sprintf("%d", val)) + case uint, uint8, uint16, uint32, uint64: + result = append(result, fmt.Sprintf("%d", val)) + case float64: + result = append(result, fmt.Sprintf("%d", int(val))) case bool: result = append(result, fmt.Sprintf("%t", val)) case string: result = append(result, val) - case []string: - result = append(result, val...) case []rune: result = append(result, string(val)) - case float64: - result = append(result, fmt.Sprintf("%d", int(val))) + case []string: + result = append(result, val...) + case time.Time: + result = append(result, fmt.Sprintf("%s", val.Format("2006-01-02 15:03:04"))) case *os.File: if s, e := val.Stat(); e == nil { result = append(result, fmt.Sprintf("%T [name: %s]", v, s.Name())) } else { result = append(result, fmt.Sprintf("%T", v)) } - case time.Time: - result = append(result, fmt.Sprintf("%d", val.Format("2006-01-02 15:03:04"))) // case error: // result = append(result, fmt.Sprintf("%v", val)) default: @@ -138,14 +175,14 @@ func Formats(arg ...interface{}) string { // result = append(result, Format(v)) // } default: - if b, e := json.MarshalIndent(val, " ", " "); e == nil { - Log("fuck", "what %v", b) + if b, e := json.MarshalIndent(val, "", " "); e == nil { result = append(result, string(b)) } } } return strings.Join(result, " ") } + func Trans(arg ...interface{}) []string { ls := []string{} for _, v := range arg { @@ -393,6 +430,9 @@ func Chain(root interface{}, args ...interface{}) interface{} { return value[key] // 读取数据 } value[key] = args[i+1] // 修改数据 + if !Right(args[i+1]) { + delete(value, key) + } } next = value[key] case []interface{}: @@ -434,30 +474,10 @@ func Chain(root interface{}, args ...interface{}) interface{} { return root } + func Link(name string, url string) string { return fmt.Sprintf("%s", url, name) } - -func Duration(arg ...string) time.Duration { - d, _ := time.ParseDuration(arg[0]) - return d -} - -func Action(cmd string, arg ...interface{}) string { - switch cmd { - case "time": - return Format(time.Now()) - case "rand": - return Format(rand.Int()) - case "uniq": - return Format(time.Now(), rand.Int()) - default: - if len(arg) > 0 { - return Format(arg...) - } - } - return cmd -} func Time(arg ...string) int { if len(arg) == 0 { return Int(time.Now()) @@ -480,14 +500,9 @@ func Time(arg ...string) int { } return 0 } -func Hash(arg ...interface{}) (string, []string) { - meta := Trans(arg...) - for i, v := range meta { - meta[i] = Action(v) - } - - h := md5.Sum([]byte(strings.Join(meta, ""))) - return hex.EncodeToString(h[:]), meta +func Duration(arg ...string) time.Duration { + d, _ := time.ParseDuration(arg[0]) + return d } func FileName(name string, meta ...string) string { result, app := strings.Split(name, "."), "" @@ -503,20 +518,19 @@ func FileName(name string, meta ...string) string { result = append(result, "_", time.Now().Format("0102")) case "time": result = append(result, "_", time.Now().Format("2006_0102_1504")) + case "rand": + result = append(result, "_", Format(rand.Int())) + case "uniq": + result = append(result, "_", Format(Time())) + result = append(result, "_", Format(rand.Int())) } } + if app != "" { result = append(result, ".", app) } return strings.Join(result, "") } - -func Check(e error) bool { - if e != nil { - panic(e) - } - return true -} func FmtSize(size uint64) string { if size > 1<<30 { return fmt.Sprintf("%d.%dG", size>>30, (size>>20)%1024*100/1024) @@ -547,6 +561,48 @@ func FmtNano(nano int64) string { return fmt.Sprintf("%dns", nano) } + +func Hash(arg ...interface{}) (string, []string) { + args := []string{} + for _, v := range Trans(arg...) { + switch v { + case "time": + args = append(args, Format(time.Now())) + case "rand": + args = append(args, Format(rand.Int())) + case "uniq": + args = append(args, Format(time.Now())) + args = append(args, Format(rand.Int())) + default: + if s, e := os.Stat(v); e == nil && !s.IsDir() { + if f, e := os.Open(v); e == nil { + defer f.Close() + m := md5.New() + io.Copy(m, f) + h := m.Sum(nil) + args = append(args, hex.EncodeToString(h[:])) + break + } + } + args = append(args, v) + } + } + + h := md5.Sum([]byte(strings.Join(args, ""))) + return hex.EncodeToString(h[:]), args +} + +func Block(root interface{}, args ...interface{}) interface{} { + + return root +} + +func Check(e error) bool { + if e != nil { + panic(e) + } + return true +} func DirWalk(file string, hand func(file string)) { s, e := os.Stat(file) Check(e)