1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-26 09:14:06 +08:00

opt ssh&aaa

Change-Id: I283075b3d1d04e48f50c69686bb31b2dc06087b1
This commit is contained in:
shaoying 2019-01-26 22:46:14 +08:00
parent 75a94fddad
commit e9a5e079f0
11 changed files with 529 additions and 577 deletions

View File

@ -13,11 +13,9 @@ import (
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
"math/rand" "math/rand"
"os"
"strings" "strings"
"time" "time"
"toolkit" "toolkit"
@ -129,6 +127,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
"userrole": map[string]interface{}{"public": true}, "userrole": map[string]interface{}{"public": true},
"password": map[string]interface{}{"secrete": true, "single": true}, "password": map[string]interface{}{"secrete": true, "single": true},
"uuid": map[string]interface{}{"secrete": true, "single": true}, "uuid": map[string]interface{}{"secrete": true, "single": true},
"ppid": map[string]interface{}{"secrete": true, "single": true},
}, Help: "散列"}, }, Help: "散列"},
"secrete_key": &ctx.Config{Name: "secrete_key", Value: map[string]interface{}{"password": 1, "uuid": 1}, 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: "私钥文件"}, "key": &ctx.Config{Name: "key", Value: "etc/pem/key.pem", Help: "私钥文件"},
}, },
Commands: map[string]*ctx.Command{ 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 { if len(arg) == 0 {
m.Cmdy("ctx.config", "hash") m.Cmdy("ctx.config", "hash")
return return
} }
if arg[0] == "file" { hs, meta := kit.Hash(arg)
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[:])
m.Log("info", "%s: %v", hs, meta) m.Log("info", "%s: %v", hs, meta)
m.Confv("hash", hs, meta) m.Confv("hash", hs, meta)
m.Echo(hs) m.Echo(hs)
@ -322,7 +297,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
m.Add("append", "create_time", node["create_time"]) m.Add("append", "create_time", node["create_time"])
} }
}) })
m.Table() m.Set("result").Table()
break break
} else if i == len(arg)-1 { // 读取链接 } else if i == len(arg)-1 { // 读取链接
if p == "" { if p == "" {
@ -349,8 +324,22 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
} }
}) })
} }
m.Table() m.Set("result").Table()
return 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" { if arg[i] == "check" {
@ -382,6 +371,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
h := m.Cmdx("aaa.hash", meta) h := m.Cmdx("aaa.hash", meta)
if !m.Confs("auth", h) { if !m.Confs("auth", h) {
if m.Confs("auth_type", []string{arg[i], "single"}) && m.Cmds("aaa.auth", p, arg[i]) { if m.Confs("auth_type", []string{arg[i], "single"}) && m.Cmds("aaa.auth", p, arg[i]) {
m.Set("result")
return // 单点认证失败 return // 单点认证失败
} }
@ -396,12 +386,10 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
if p != "" { // 创建父链接 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": 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": ""}) 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] p, t, a = h, arg[i], meta[1]
m.Set("result").Echo(h) m.Echo(h)
case "node": // 节点操作 case "node": // 节点操作
if i > len(arg)-1 { // 查看节点 if i > len(arg)-1 { // 查看节点
m.Cmdy("aaa.config", "auth", p) m.Cmdy("aaa.config", "auth", p)
@ -462,30 +450,29 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
} }
return 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 { Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
switch len(arg) { switch len(arg) {
case 0: case 0: // 查看角色
Auto(m, "ship", "userrole") 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 return true
}, },
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) { switch len(arg) {
case 0: case 0: // 查看角色
m.Cmdy("aaa.auth", "ship", "userrole") m.Cmdy("aaa.auth", "ship", "userrole")
case 1: case 1: // 查看组件
m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet") m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet")
case 2: case 2: // 查看功能
m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond") m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "command")
case 3: case 3: // 查看接口
if arg[1] == "componet" { m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "command", arg[2], "componet")
m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2]) default: // 添加接口
} else {
m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond", arg[2])
}
case 4:
default:
if arg[1] == "componet" && arg[3] == "command" { if arg[1] == "componet" && arg[3] == "command" {
for _, v := range arg[4:] { for _, v := range arg[4:] {
m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2], "command", v) 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: "用户认证", "user": &ctx.Command{Name: "user [role username password] [username]", Help: "用户认证",
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
switch len(arg) { switch len(arg) {
case 0: case 0: // 查看用户
Auto(m, "ship", "username") Auto(m, "ship", "username")
case 1: // 查看会话
Auto(m, "ship", "username", arg[0], "session")
} }
return true return true
}, },
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) { switch len(arg) {
case 0: case 0: // 查看用户
m.Cmdy("aaa.auth", "ship", "username") m.Cmdy("aaa.auth", "ship", "username")
case 1: case 1: // 查看角色
m.Cmd("aaa.auth", "ship", "username", arg[0], "userrole").CopyTo(m, "append") m.Cmdy("aaa.auth", "ship", "username", arg[0], "userrole")
case 3: 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") { 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]) m.Cmdy("aaa.auth", "username", arg[0], arg[1], arg[2])
break break
} }
fallthrough fallthrough
default: default: // 添加用户
for i := 1; i < len(arg); i += 2 { 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]) m.Cmd("aaa.auth", "ship", "username", arg[i], "password", arg[i+1])
} }
} }
} }
return 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 { Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
switch len(arg) { switch len(arg) {
case 0: case 0: // 查看会话
Auto(m, "ship", "session") Auto(m, "ship", "session")
case 1: case 1: // 查看会话
m.Auto("username", "username", "查看用户") Auto(m, "ship", "session", arg[0])
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"])
})
} }
return true return true
}, },
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) { switch len(arg) {
case 0: case 0: // 查看会话
m.Cmdy("aaa.auth", "ship", "session") m.Cmdy("aaa.auth", "ship", "session")
case 1: case 1: // 查看会话
m.Cmdy("aaa.auth", arg[0]) m.Cmdy("aaa.auth", arg[0])
case 2: // 查询会话
case 2: m.Cmdy("aaa.auth", arg[0], "ship", arg[1])
switch arg[1] { case 3: // 创建会话
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:
m.Cmdy("aaa.auth", "ship", "session", arg[0], arg[1], arg[2]) 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]) m.Cmdy("aaa.auth", arg[0], "ship", "username", arg[1], arg[2], arg[3])
} }
return 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) { Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (goon bool) {
switch len(arg) { switch len(arg) {
case 0: case 0:
@ -601,65 +568,45 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
return true return true
}, },
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { 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") m.Cmdy("aaa.auth", "ship", "bench")
return return
} }
bid := "" bid := ""
switch m.Conf("auth", []string{arg[0], "type"}) { switch m.Conf("auth", []string{arg[0], "type"}) {
case "session": case "session": // 创建空间
if len(arg) == 1 { bid, arg = m.Cmdx("aaa.auth", arg[0], "ship", "bench", arg[1]), arg[2:]
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") m.Cmd("aaa.auth", bid, "data", "name", "web")
defer func() { m.Set("result").Echo(bid) }() defer func() { m.Set("result").Echo(bid) }()
case "select": case "bench": // 查询空间
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":
bid, arg = arg[0], arg[1:] bid, arg = arg[0], arg[1:]
default: default:
return return
} }
if len(arg) == 0 { if len(arg) == 0 {
m.Echo(bid) m.Echo(bid)
return return
} }
switch arg[0] { switch arg[0] {
case "delete": case "delete": // 删除空间
m.Cmd("aaa.auth", bid, "delete", "node") m.Cmd("aaa.auth", bid, "delete", "node")
case "rename": case "rename": // 命名空间
m.Cmd("aaa.auth", bid, "data", "name", arg[1]) 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) { 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") m.Echo("true")
} else if len(arg) >= 4 { } else if len(arg) >= 4 { // 功能权限
if m.Cmds("aaa.auth", bid, "ship", "check", arg[3]) { if m.Cmds("aaa.auth", bid, "ship", "check", arg[3]) {
m.Echo("true") m.Echo("true")
} else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "componet", arg[2], "check", arg[3]); kit.Right(cid) { } 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.Cmd("aaa.auth", bid, cid)
m.Echo("true") m.Echo("true")
} }
} else if len(arg) >= 3 { } else if len(arg) >= 3 { // 组件权限
if m.Cmds("aaa.auth", bid, "ship", "check", arg[2]) { if m.Cmds("aaa.auth", bid, "ship", "check", arg[2]) {
m.Echo("true") m.Echo("true")
} else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "check", arg[2]); kit.Right(cid) { } 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) m.Cmdx("aaa.auth", bid, arg)
} }
return 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", "rsa": &ctx.Command{Name: "rsa gen|sign|verify|encrypt|decrypt|cert",
Help: []string{"gen: 生成密钥, sgin: 私钥签名, verify: 公钥验签, encrypt: 公钥加密, decrypt: 私钥解密", Help: []string{"gen: 生成密钥, sgin: 私钥签名, verify: 公钥验签, encrypt: 公钥加密, decrypt: 私钥解密",
"密钥: rsa gen [keyfile [pubfile [certfile]]]", "密钥: rsa gen [keyfile [pubfile [certfile]]]",

View File

@ -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 arg[0] = p
switch path.Ext(p) { switch path.Ext(p) {
case "": case "":

View File

@ -72,7 +72,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
"debug": &Config{Name: "debug(on/off)", Value: "on", Help: "调试模式on:打印off:不打印)"}, "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_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_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: 当前模块"}, "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() m.Sort("key", "string").Table()
return 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) { "result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
msg := m.message msg := m.message
if len(arg) == 0 { 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]", "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) { Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
if len(arg) == 1 && arg[0] == "~" && m.target.context != nil { if len(arg) == 1 && arg[0] == "~" && m.target.context != nil {
m.target = m.target.context 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:] ms, arg = append(ms, msg[len(msg)-1]), arg[2:]
case "rand": case "rand":
ms, arg = append(ms, msg[rand.Intn(len(msg))]), arg[2:] ms, arg = append(ms, msg[rand.Intn(len(msg))]), arg[2:]
case "magic": case "magics":
ms, arg = append(ms, msg...), arg[2:] ms, arg = append(ms, msg...), arg[2:]
default: default:
ms, arg = append(ms, msg[0]), arg[1:] 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]", "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: 删除配置", Help: "配置管理, export: 导出配置, save: 保存配置到文件, load: 从文件加载配置, create: 创建配置, delete: 删除配置",
Form: map[string]int{"format": 1},
Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
if len(arg) > 2 && arg[2] == "list" { if len(arg) > 2 && arg[2] == "list" {
chain := strings.Split(arg[1], ".") chain := strings.Split(arg[1], ".")
@ -942,7 +957,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
return 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) { "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:] value, arg := m.Optionv(arg[0]), arg[1:]
if v, ok := value.(string); ok { if v, ok := value.(string); ok {
json.Unmarshal([]byte(v), &value) json.Unmarshal([]byte(v), &value)
@ -960,7 +977,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
if len(arg) > 0 && arg[0] == "limit" { if len(arg) > 0 && arg[0] == "limit" {
limit, arg = kit.Int(arg[1]), arg[2:] limit, arg = kit.Int(arg[1]), arg[2:]
} }
m.Log("fuck", "trans limt %v", limit)
chain := strings.Join(arg, ".") chain := strings.Join(arg, ".")
if chain != "" { if chain != "" {
@ -1000,6 +1016,11 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
switch val := value.(type) { switch val := value.(type) {
case map[string]interface{}: case map[string]interface{}:
for k, v := range val { for k, v := range val {
if m.Option("format") == "object" {
m.Add("append", k, v)
continue
}
m.Add("append", "key", k) m.Add("append", "key", k)
switch val := v.(type) { switch val := v.(type) {
case nil: case nil:
@ -1013,7 +1034,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
m.Add("append", "value", fmt.Sprintf("%s", string(b))) m.Add("append", "value", fmt.Sprintf("%s", string(b)))
} }
} }
m.Sort("key", "str").Table() m.Table()
// m.Sort("key", "str").Table()
case map[string]string: case map[string]string:
for k, v := range val { for k, v := range val {
m.Add("append", "key", k) m.Add("append", "key", k)

View File

@ -598,6 +598,9 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:]) m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:])
} }
case "option", "append": case "option", "append":
if msg.Meta == nil {
msg.Meta = map[string][]string{}
}
if msg.Meta[meta] == nil { if msg.Meta[meta] == nil {
break break
} }
@ -762,6 +765,35 @@ func (m *Message) Optionx(key string, arg ...string) interface{} {
} }
return value 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 { func (m *Message) Append(key string, arg ...interface{}) string {
if len(arg) > 0 { if len(arg) > 0 {
m.Insert(key, 0, arg...) m.Insert(key, 0, arg...)

View File

@ -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"}}}, "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"}}}, "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"}}}, "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"}}, "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"}}, "start": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},

View File

@ -878,10 +878,14 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
nfs.Configs["prompt"] = &ctx.Config{Value: ""} nfs.Configs["prompt"] = &ctx.Config{Value: ""}
if nfs.in = m.Optionv("in").(*os.File); m.Has("out") { 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") nfs.Term(m, "init")
defer nfs.Term(m, "exit") defer nfs.Term(m, "exit")
} }
what := make(chan bool)
if m.Confs("term", "loop") {
<-what
}
} }
line, bio := "", bufio.NewScanner(nfs) 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")) 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.send = make(chan *ctx.Message, 10)
nfs.echo = make(chan *ctx.Message, 10) nfs.echo = make(chan *ctx.Message, 10)
nfs.hand = map[int]*ctx.Message{} nfs.hand = map[int]*ctx.Message{}
@ -1023,6 +1027,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"term": &ctx.Config{Name: "term", Value: map[string]interface{}{ "term": &ctx.Config{Name: "term", Value: map[string]interface{}{
"enable": 1, "loop": 0,
"width": 80, "height": "24", "width": 80, "height": "24",
"left": 0, "top": 0, "right": 80, "bottom": 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) { "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) { //{{{ if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message { m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
if sub.Options("hostport") {
return sub
}
sub.Sess("ms_source", sub) sub.Sess("ms_source", sub)
sub.Sess("ms_target", m.Source()) sub.Sess("ms_target", m.Source())
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件") sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")

View File

@ -39,82 +39,93 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"host": &ctx.Config{Name: "host", Value: map[string]interface{}{}, Help: "主机信息"}, "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: "主机域名"}, "hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机域名"},
"current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"}, "current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"},
"timer": &ctx.Config{Name: "timer", Value: "", Help: "当前主机"}, "timer": &ctx.Config{Name: "timer", Value: "", Help: "当前主机"},
}, },
Commands: map[string]*ctx.Command{ 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) { "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 { if len(arg) == 0 { // 查看主机
m.Cmdy("ctx.config", "host") m.Cmdy("ctx.config", "host")
return return
} }
switch arg[0] { switch arg[0] {
case "redial": case "redial": // 断线重连
if !m.Caps("hostname") { if !m.Caps("hostname") {
m.Cmdx("remote", "dial", arg[1:]) m.Cmdx("remote", "dial", arg[1:])
} }
case "listen", "dial": case "listen", "dial":
m.Call(func(nfs *ctx.Message) *ctx.Message { m.Call(func(nfs *ctx.Message) *ctx.Message {
if arg[0] == "dial" { if arg[0] == "listen" && nfs.Options("hostport") { // 监听端口
if m.Confs("timer") { 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.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"), "module": nfs.Format("target"),
"create_time": m.Time(), "create_time": m.Time(),
"access_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") { 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.Conf("timer", m.Cmdx("cli.timer", "repeat", "10s", "context", "ssh", "remote", "redial", arg[1:]))
m.Log("info", "delete host %s", cmd.Result(1)) m.Log("info", "delete host %s", host.Result(1))
delete(m.Confm("host"), cmd.Result(1)) delete(m.Confm("host"), host.Result(1))
m.Cap("hostname", "") m.Cap("hostname", "")
m.Cap("stream", "") m.Cap("stream", "")
return true return true
}) })
return nil return nil
}, "send", "recv", "add", m.Conf("hostname")) }, "send", "recv", "add", m.Confx("hostname"))
} }
return nil return nil
}, "nfs.remote", arg) }, "nfs.remote", arg)
case "recv": case "recv":
switch arg[1] { switch arg[1] {
case "add": 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{}{ m.Confv("host", arg[2], map[string]interface{}{
"module": m.Format("source"), "module": m.Format("source"),
"create_time": m.Time(), "create_time": m.Time(),
"access_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["access_time"] = m.Time()
host["module"] = m.Format("source") host["module"] = m.Format("source")
} else { } else { // 域名冲突
arg[2] = fmt.Sprintf("%s_%d", arg[2], m.Capi("nhost", 1)) arg[2] = fmt.Sprintf("%s_%d", arg[2], m.Capi("nhost", 1))
m.Confv("host", arg[2], map[string]interface{}{ m.Confv("host", arg[2], map[string]interface{}{
"module": m.Format("source"), "module": m.Format("source"),
"create_time": m.Time(), "create_time": m.Time(),
"access_time": m.Time(), "access_time": m.Time(),
"username": m.Option("right"),
"cm_target": "ctx.web.code",
}) })
} }
if !m.Confs("current") { if !m.Confs("current") {
m.Conf("current", arg[2]) m.Conf("current", arg[2])
} }
m.Echo(arg[2]).Echo(m.Cap("hostname")).Back(m) 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]) m.Log("info", "delete host %s", arg[2])
delete(m.Confm("host"), arg[2]) delete(m.Confm("host"), arg[2])
return true return true
@ -122,44 +133,58 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
} }
default: default:
names := strings.SplitN(arg[0], ".", 2) names, arg := strings.SplitN(arg[0], ".", 2), arg[1:]
if names[0] == "" { // 本地执行 if names[0] == "" { // 本地执行
host := m.Confm("host", m.Option("hostname")) 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:]) sessid := m.Cmd("aaa.user", user, "ssh").Append("meta")
m.Copy(msg, "append").Copy(msg, "result") 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") host["cm_target"] = msg.Cap("module")
} else {
m.Echo("no right %s %s", "remote", arg[0])
}
// 返回结果
m.Back(m) m.Back(m)
return return
} }
m.Option("hostname", m.Cap("hostname")) //同步或异步
sync := !m.Options("remote_code") //同步或异步 sync := !m.Options("remote_code")
if arg[1] == "async" { switch arg[0] {
sync, arg = false, arg[2:] case "async", "sync":
} else if arg[1] == "sync" { sync, arg = arg[0] == "sync", arg[1:]
sync, arg = true, arg[2:]
} else {
arg = arg[1:]
} }
rest := kit.Select("", names, 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.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 { 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") return m.Copy(sub, "append").Copy(sub, "result")
}, "send", "", arg) }, "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 { 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") return m.Copy(sub, "append").Copy(sub, "result")
}, "send", rest, arg) }, "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 { 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") return m.Copy(sub, "append").Copy(sub, "result")
}, "send", strings.Join(names, "."), arg) }, "send", strings.Join(names, "."), arg)

View File

@ -55,6 +55,18 @@ func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server {
return tcp return tcp
} }
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { 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("address", m.Confx("address", arg, 1))
m.Cap("security", m.Confx("security", arg, 2)) m.Cap("security", m.Confx("security", arg, 2))
m.Cap("protocol", m.Confx("protocol", arg, 3)) 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.Log("info", "%d listen %v", m.Capi("nlisten"),
m.Cap("stream", fmt.Sprintf("%s", tcp.Addr()))) 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 { for {
@ -151,6 +167,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心",
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}, "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"": &ctx.Config{Name: "address", Value: ":9090", Help: "网络地址"},
"address": &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: "加密通信"}, "security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"},
"protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"}, "protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"},
@ -185,19 +202,22 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心",
} }
return 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) { if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs { for _, v := range ifs {
if ips, e := v.Addrs(); m.Assert(e) { if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips { 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", "index", v.Index)
m.Add("append", "name", v.Name) m.Add("append", "name", v.Name)
m.Add("append", "hard", v.HardwareAddr) m.Add("append", "hard", v.HardwareAddr)
m.Add("append", "ip", ip) m.Add("append", "ip", ip[0])
} }
} }
} }

View File

@ -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 { 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 msg.Confs("login", "cas_url") && !msg.Confs("login", "skip_cas") {
if !cas.IsAuthenticated(r) { if !cas.IsAuthenticated(r) {
r.URL, _ = r.URL.Parse(r.Header.Get("index_url")) 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") { if msg.Options("ticket") {
msg.Log("fuck", "what %v", msg.Meta)
msg.Option("uuid", msg.Option(msg.Conf("login", "cas_uuid"))) msg.Option("uuid", msg.Option(msg.Conf("login", "cas_uuid")))
msg.Option("username", cas.Username(r)) msg.Option("username", cas.Username(r))
if lark := msg.Find("web.chat.lark"); lark != nil { if lark := msg.Find("web.chat.lark"); lark != nil {
msg.Option("username", lark.Cmdx("user", msg.Option("email"), "id")) 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.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) 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 return false
} }
if !msg.Options("current_ctx") {
http.SetCookie(w, &http.Cookie{Name: "current_ctx", Value: msg.Option("current_ctx", "mdb"), Path: "/"})
}
return true return true
} }
func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { 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) req, e := http.NewRequest(method, uri, body)
m.Assert(e) m.Assert(e)
m.Log("info", "%s %s", req.Method, req.URL) m.Log("info", "%s %s", req.Method, req.URL)
@ -789,7 +796,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
switch arg[0] { switch arg[0] {
case "login": case "login":
if len(arg) == 1 { if len(arg) == 1 { // 查询用户
m.Echo(m.Cmd("aaa.sess", sessid, "username").Append("meta")) m.Echo(m.Cmd("aaa.sess", sessid, "username").Append("meta"))
break break
} }
@ -797,25 +804,26 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
if username == "" || !m.Options(arg[1]) { if username == "" || !m.Options(arg[1]) {
break 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")) 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) m.Echo(sessid)
} }
case "bench": case "bench":
if len(arg) == 1 { if len(arg) == 1 { // 创建空间
bench := m.Option("bench") bench := m.Option("bench")
if bench == "" || !m.Cmds("aaa.work", bench) { // 创建空间 if bench == "" || !m.Cmds("aaa.work", bench) {
bench = m.Cmdx("aaa.work", sessid, "create", "web") bench = m.Cmdx("aaa.work", sessid, "web")
} }
m.Echo(bench) m.Echo(bench)
break break
} }
// 添加数据
m.Cmd("aaa.work", arg[1:]) m.Cmd("aaa.work", arg[1:])
case "check": case "check": // 检查权限
m.Echo(m.Cmdx("aaa.work", arg[1], "right", arg[2:])) m.Echo(m.Cmdx("aaa.work", arg[1], "right", arg[2:]))
} }
return 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 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 == "" { if list := m.Confv("auth", []string{m.Option("bench"), "data", "action", msg.Option("componet_name"), "cmd"}); list != nil && order == "" {

View File

@ -5,12 +5,17 @@ import (
"contexts/web" "contexts/web"
"fmt" "fmt"
"net/http" "net/http"
"os"
"strconv" "strconv"
"time"
) )
var Index = &ctx.Context{Name: "code", Help: "代码中心", var Index = &ctx.Context{Name: "code", Help: "代码中心",
Caches: map[string]*ctx.Cache{}, Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{ 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{}{ "counter": &ctx.Config{Name: "counter", Value: map[string]interface{}{
"nopen": "0", "nsave": "0", "nopen": "0", "nsave": "0",
}, Help: "counter"}, }, Help: "counter"},
@ -209,9 +214,10 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
}, Help: "组件列表"}, }, Help: "组件列表"},
"upgrade": &ctx.Config{Name: "upgrade", Value: map[string]interface{}{ "upgrade": &ctx.Config{Name: "upgrade", Value: map[string]interface{}{
"file": map[string]interface{}{ "file": map[string]interface{}{
"init_shy": "etc/init0.shy", "init_shy": "etc/init.shy",
"common_shy": "etc/common.shy",
"exit_shy": "etc/exit.shy", "exit_shy": "etc/exit.shy",
"bench": "bin/bench", "bench": "bin/bench.new",
}, },
}, Help: "日志地址"}, }, Help: "日志地址"},
}, },
@ -250,21 +256,49 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
return return
}}, }},
"upgrade": &ctx.Command{Name: "upgrade system|script", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "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.Cmd("cli.source", m.Conf("exit.shy"))
m.Confm("upgrade", "file", func(key string, value string) { m.Confm("upgrade", "file", func(key string, value string) {
m.Cmd("web.get", "dev", fmt.Sprintf("code/upgrade/%s", key), "save", value) m.Cmd("web.get", "dev", fmt.Sprintf("code/upgrade/%s", key), "save", value)
}) })
m.Cmd("cli.system", "chmod", "u+x", "bin/bench") m.Cmd("cli.system", "chmod", "u+x", "bin/bench.new")
// os.Exit(1) 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 return
} }
m.Cmdy("web.get", "dev", fmt.Sprintf("code/upgrade/script/%s", arg[0]), "save", fmt.Sprintf("usr/script/%s", arg[0]), arg[1:]) m.Cmdy("web.get", "dev", fmt.Sprintf("code/upgrade/script/%s", arg[0]), "save", fmt.Sprintf("usr/script/%s", arg[0]), arg[1:])
return 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
}},
}, },
} }

View File

@ -5,6 +5,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"strconv" "strconv"
"strings" "strings"
@ -37,17 +38,46 @@ func Int(arg ...interface{}) int {
switch val := v.(type) { switch val := v.(type) {
case int: case int:
result += val result += val
case bool: case int8:
if val { result += int(val)
result += 1 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: case string:
if i, e := strconv.Atoi(val); e == nil { if i, e := strconv.Atoi(val); e == nil {
result += i result += i
} }
case bool:
if val {
result += 1
}
case time.Time: case time.Time:
result += int(val.Unix()) 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 return result
@ -64,12 +94,19 @@ func Right(arg ...interface{}) bool {
switch val { switch val {
case "", "0", "false", "off", "no", "error: ": case "", "0", "false", "off", "no", "error: ":
result = result || false result = result || false
break
default: default:
result = result || true result = result || true
} }
case error: case error:
result = result || false 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: default:
result = result || val != nil result = result || val != nil
} }
@ -82,28 +119,28 @@ func Format(arg ...interface{}) string {
switch val := v.(type) { switch val := v.(type) {
case nil: case nil:
result = result[:0] result = result[:0]
case uint, uint8, uint16, uint32, uint64:
result = append(result, fmt.Sprintf("%d", val))
case int, int8, int16, int32, int64: case int, int8, int16, int32, int64:
result = append(result, fmt.Sprintf("%d", val)) 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: case bool:
result = append(result, fmt.Sprintf("%t", val)) result = append(result, fmt.Sprintf("%t", val))
case string: case string:
result = append(result, val) result = append(result, val)
case []string:
result = append(result, val...)
case []rune: case []rune:
result = append(result, string(val)) result = append(result, string(val))
case float64: case []string:
result = append(result, fmt.Sprintf("%d", int(val))) result = append(result, val...)
case time.Time:
result = append(result, fmt.Sprintf("%s", val.Format("2006-01-02 15:03:04")))
case *os.File: case *os.File:
if s, e := val.Stat(); e == nil { if s, e := val.Stat(); e == nil {
result = append(result, fmt.Sprintf("%T [name: %s]", v, s.Name())) result = append(result, fmt.Sprintf("%T [name: %s]", v, s.Name()))
} else { } else {
result = append(result, fmt.Sprintf("%T", v)) 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: // case error:
// result = append(result, fmt.Sprintf("%v", val)) // result = append(result, fmt.Sprintf("%v", val))
default: default:
@ -139,13 +176,13 @@ func Formats(arg ...interface{}) string {
// } // }
default: default:
if b, e := json.MarshalIndent(val, "", " "); e == nil { if b, e := json.MarshalIndent(val, "", " "); e == nil {
Log("fuck", "what %v", b)
result = append(result, string(b)) result = append(result, string(b))
} }
} }
} }
return strings.Join(result, " ") return strings.Join(result, " ")
} }
func Trans(arg ...interface{}) []string { func Trans(arg ...interface{}) []string {
ls := []string{} ls := []string{}
for _, v := range arg { for _, v := range arg {
@ -393,6 +430,9 @@ func Chain(root interface{}, args ...interface{}) interface{} {
return value[key] // 读取数据 return value[key] // 读取数据
} }
value[key] = args[i+1] // 修改数据 value[key] = args[i+1] // 修改数据
if !Right(args[i+1]) {
delete(value, key)
}
} }
next = value[key] next = value[key]
case []interface{}: case []interface{}:
@ -434,30 +474,10 @@ func Chain(root interface{}, args ...interface{}) interface{} {
return root return root
} }
func Link(name string, url string) string { func Link(name string, url string) string {
return fmt.Sprintf("<a href=\"%s\" target=\"_blank\">%s</a>", url, name) return fmt.Sprintf("<a href=\"%s\" target=\"_blank\">%s</a>", 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 { func Time(arg ...string) int {
if len(arg) == 0 { if len(arg) == 0 {
return Int(time.Now()) return Int(time.Now())
@ -480,14 +500,9 @@ func Time(arg ...string) int {
} }
return 0 return 0
} }
func Hash(arg ...interface{}) (string, []string) { func Duration(arg ...string) time.Duration {
meta := Trans(arg...) d, _ := time.ParseDuration(arg[0])
for i, v := range meta { return d
meta[i] = Action(v)
}
h := md5.Sum([]byte(strings.Join(meta, "")))
return hex.EncodeToString(h[:]), meta
} }
func FileName(name string, meta ...string) string { func FileName(name string, meta ...string) string {
result, app := strings.Split(name, "."), "" result, app := strings.Split(name, "."), ""
@ -503,20 +518,19 @@ func FileName(name string, meta ...string) string {
result = append(result, "_", time.Now().Format("0102")) result = append(result, "_", time.Now().Format("0102"))
case "time": case "time":
result = append(result, "_", time.Now().Format("2006_0102_1504")) 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 != "" { if app != "" {
result = append(result, ".", app) result = append(result, ".", app)
} }
return strings.Join(result, "") return strings.Join(result, "")
} }
func Check(e error) bool {
if e != nil {
panic(e)
}
return true
}
func FmtSize(size uint64) string { func FmtSize(size uint64) string {
if size > 1<<30 { if size > 1<<30 {
return fmt.Sprintf("%d.%dG", size>>30, (size>>20)%1024*100/1024) 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) 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)) { func DirWalk(file string, hand func(file string)) {
s, e := os.Stat(file) s, e := os.Stat(file)
Check(e) Check(e)