forked from x/ContextOS
opt ssh
This commit is contained in:
parent
23f0bb07b0
commit
8e1b86d554
@ -1,5 +1,3 @@
|
||||
~ssh
|
||||
config trust up true
|
||||
~mdb
|
||||
note model favor spirit spirit relate relate
|
||||
note model money expend expend amount amount
|
||||
|
@ -1,5 +1,5 @@
|
||||
~code
|
||||
config save tmp/flash.json flash
|
||||
~ssh
|
||||
config save tmp/cert.json cert trust
|
||||
~aaa
|
||||
config save tmp/auth.json auth
|
||||
~cli
|
||||
|
@ -2,8 +2,8 @@
|
||||
config load tmp/runtime.json runtime
|
||||
~aaa
|
||||
config load tmp/auth.json auth
|
||||
~code
|
||||
config load tmp/flash.json flash
|
||||
~ssh
|
||||
config load tmp/cert.json cert trust
|
||||
|
||||
source etc/common.shy
|
||||
~ssh
|
||||
|
@ -461,7 +461,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
for i := 1; i < len(arg); i++ { // 添加用户
|
||||
if m.Cmd("aaa.auth", "ship", "username", arg[i], "userrole", role); i < len(arg)-2 {
|
||||
switch arg[i+1] {
|
||||
case "password", "uuid":
|
||||
case "password", "uuid", "cert":
|
||||
m.Cmd("aaa.auth", "ship", "username", arg[i], arg[i+1], arg[i+2])
|
||||
i += 2
|
||||
}
|
||||
@ -628,26 +628,30 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||
|
||||
// 检查权限
|
||||
m.Cmd("aaa.auth", "ship", "username", m.Option("username"), "userrole").Table(func(node map[string]string) {
|
||||
if node["meta"] == "root" { // 超级用户
|
||||
m.Log("info", "role: root")
|
||||
m.Echo("true")
|
||||
if m.Options("userrole") && node["meta"] != m.Option("userrole") {
|
||||
return // 失败
|
||||
} else if node["meta"] == "root" { // 超级用户
|
||||
|
||||
} else if len(arg) > 2 { // 接口权限
|
||||
if m.Cmds("aaa.auth", m.Option("bench"), "ship", "check", arg[2]) {
|
||||
m.Echo("true")
|
||||
|
||||
} else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "componet", arg[1], "check", arg[2]); kit.Right(cid) {
|
||||
m.Log("info", "role: %s", node["meta"])
|
||||
m.Cmd("aaa.auth", m.Option("bench"), cid)
|
||||
m.Echo("true")
|
||||
} else {
|
||||
return // 失败
|
||||
}
|
||||
} else if len(arg) > 1 { // 组件权限
|
||||
if m.Cmds("aaa.auth", m.Option("bench"), "ship", "check", arg[1]) {
|
||||
m.Echo("true")
|
||||
|
||||
} else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "check", arg[1]); kit.Right(cid) {
|
||||
m.Log("info", "role: %s", node["meta"])
|
||||
m.Cmd("aaa.auth", m.Option("bench"), cid)
|
||||
m.Echo("true")
|
||||
} else {
|
||||
return // 失败
|
||||
}
|
||||
}
|
||||
|
||||
m.Log("info", "role: %s %v", node["meta"], arg[1:])
|
||||
m.Echo(node["meta"])
|
||||
})
|
||||
|
||||
m.Log("right", "bench: %s sessid: %s user: %s com: %v result: %v",
|
||||
|
@ -466,11 +466,15 @@ func (m *Message) Format(arg ...interface{}) string {
|
||||
}
|
||||
}
|
||||
|
||||
meta = append(meta, "\n")
|
||||
for i := len(ms) - 1; i >= 0; i-- {
|
||||
msg := ms[i]
|
||||
|
||||
meta = append(meta, fmt.Sprintf("\n%s\n", msg.Format("time", "ship")))
|
||||
meta = append(meta, fmt.Sprintf("%s\n", msg.Format("time", "ship")))
|
||||
if len(msg.Meta["detail"]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" detail: %d %v\n", len(msg.Meta["detail"]), msg.Meta["detail"]))
|
||||
}
|
||||
if len(msg.Meta["option"]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" option: %d %v\n", len(msg.Meta["option"]), msg.Meta["option"]))
|
||||
for _, k := range msg.Meta["option"] {
|
||||
if v, ok := msg.Data[k]; ok {
|
||||
@ -479,6 +483,8 @@ func (m *Message) Format(arg ...interface{}) string {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(msg.Meta["append"]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" append: %d %v\n", len(msg.Meta["append"]), msg.Meta["append"]))
|
||||
for _, k := range msg.Meta["append"] {
|
||||
if v, ok := msg.Data[k]; ok {
|
||||
@ -487,11 +493,14 @@ func (m *Message) Format(arg ...interface{}) string {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(msg.Meta["result"]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" result: %d %v\n", len(msg.Meta["result"]), msg.Meta["result"]))
|
||||
}
|
||||
}
|
||||
case "stack":
|
||||
pc := make([]uintptr, 100)
|
||||
pc = pc[:runtime.Callers(2, pc)]
|
||||
pc = pc[:runtime.Callers(6, pc)]
|
||||
frames := runtime.CallersFrames(pc)
|
||||
|
||||
for {
|
||||
@ -1570,7 +1579,7 @@ func (m *Message) Cmd(args ...interface{}) *Message {
|
||||
msg := m
|
||||
if strings.Contains(key, ":") {
|
||||
ps := strings.Split(key, ":")
|
||||
msg, key, arg = msg.Sess("ssh"), "sh", append([]string{"node", ps[0], "sync", ps[1]}, arg...)
|
||||
msg, key, arg = msg.Sess("ssh"), "remote", append([]string{"sync", ps[0], ps[1]}, arg...)
|
||||
defer func() { m.Copy(msg, "append").Copy(msg, "result") }()
|
||||
m.Hand = true
|
||||
|
@ -1,115 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCtx(t *testing.T) {
|
||||
context := Context{Name: "root", Help: "默认",
|
||||
Caches: map[string]*Cache{
|
||||
"nclient": &Cache{"nclient", "10", "连接数量", func(c *Context) string {
|
||||
return "10"
|
||||
}},
|
||||
},
|
||||
Configs: map[string]*Config{
|
||||
"limit": &Config{"limit", "10", "最大连接数", func(c *Context, arg string) {
|
||||
}},
|
||||
},
|
||||
Commands: map[string]*Command{
|
||||
"session": &Command{"session", "会话管理", func(c *Context, arg ...string) string {
|
||||
return "ok"
|
||||
}},
|
||||
},
|
||||
}
|
||||
context.Index = map[string]*Context{"root": &context}
|
||||
|
||||
ctx := context.Index["root"]
|
||||
ctx.Add("context", "hi", "hi", "nice")
|
||||
if _, ok := context.Contexts["hi"]; !ok {
|
||||
t.Fatal("root.ctxs add error")
|
||||
}
|
||||
if c, ok := context.Index["hi"]; ok {
|
||||
ctx.Add("command", "hi", "session")
|
||||
if _, ok := c.Commands["session"]; ok {
|
||||
if c.Cmd("session") != "ok" {
|
||||
t.Fatal("hi.cmds.session: run error")
|
||||
}
|
||||
} else {
|
||||
t.Fatal("hi.cmds: add error")
|
||||
}
|
||||
|
||||
ctx.Add("config", "hi", "limit")
|
||||
ctx.Add("cache", "hi", "nclient")
|
||||
|
||||
} else {
|
||||
t.Fatal("root.index add error")
|
||||
}
|
||||
return
|
||||
|
||||
if true {
|
||||
ctx := context.Index["hi"]
|
||||
if ctx.Cmd("session", "nice") == "ok" {
|
||||
t.Log("hi.cmds.session: run")
|
||||
} else {
|
||||
t.Fatal("hi.cmds.session: run error")
|
||||
}
|
||||
t.Log()
|
||||
|
||||
ctx.Add("context", "he", "he", "nice")
|
||||
for k, v := range ctx.Contexts {
|
||||
t.Log("hi.ctxs", k, v.Name, v.Help)
|
||||
}
|
||||
if len(ctx.Contexts) != 1 {
|
||||
t.Fatal("hi.ctxs: add error")
|
||||
}
|
||||
for k, v := range ctx.Index {
|
||||
t.Log("hi.index:", k, v.Name, v.Help)
|
||||
}
|
||||
if len(ctx.Index) != 3 {
|
||||
t.Fatal("hi.index: add error")
|
||||
}
|
||||
t.Log()
|
||||
|
||||
ctx.Add("command", "he", "session")
|
||||
for k, v := range ctx.Contexts["he"].Commands {
|
||||
t.Log("he.cmds:", k, v.Name, v.Help)
|
||||
}
|
||||
if len(ctx.Contexts["he"].Commands) != 1 {
|
||||
t.Fatal("he.cmds: add error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for k, v := range ctx.Index {
|
||||
t.Log("root.index:", k, v.Name, v.Help)
|
||||
}
|
||||
if len(ctx.Index) != 3 {
|
||||
t.Fatal("root.index add error")
|
||||
}
|
||||
t.Log()
|
||||
|
||||
for k, v := range ctx.Index {
|
||||
t.Log(fmt.Sprintf("root.index.%s.cmds: %d", k, len(v.Commands)))
|
||||
}
|
||||
t.Log()
|
||||
ctx.Del("command", "hi", "session")
|
||||
for k, v := range ctx.Index {
|
||||
t.Log(fmt.Sprintf("root.index.%s.cmds: %d", k, len(v.Commands)))
|
||||
}
|
||||
t.Log()
|
||||
|
||||
ctx.Del("context", "hi")
|
||||
for k, v := range ctx.Contexts {
|
||||
t.Log("root.ctxs:", k, v.Name, v.Help)
|
||||
}
|
||||
if len(ctx.Contexts) != 0 {
|
||||
t.Fatal("root.ctxs: del error")
|
||||
}
|
||||
for k, v := range ctx.Index {
|
||||
t.Log("root.index:", k, v.Name, v.Help)
|
||||
}
|
||||
if len(ctx.Index) != 1 {
|
||||
t.Fatal("root.index del error")
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package gdb
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLog(t *testing.T) {
|
||||
m := ctx.Pulse.Spawn(Index)
|
||||
m.Sess("gdb", m)
|
||||
m.Target().Begin(m).Start(m)
|
||||
|
||||
go func() {
|
||||
t.Logf("%s", m.Cmd("wait", "config", "demo").Result(0))
|
||||
|
||||
// t.Logf("%s", m.Cmd("demo", "what").Result(0))
|
||||
}()
|
||||
|
||||
time.Sleep(time.Second * 3)
|
||||
|
||||
m.Spawn().Cmd("goon", "nice")
|
||||
|
||||
// gdb := m.Target().Server.(*GDB)
|
||||
// gdb.Goon("yes", "command", "demo")
|
||||
//
|
||||
time.Sleep(time.Second * 3)
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
package lex
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLEX(t *testing.T) {
|
||||
|
||||
m := ctx.Pulse.Spawn(Index)
|
||||
seed := map[string]map[string]string{
|
||||
// "shy?": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "sh",
|
||||
// "she": "sh",
|
||||
// "shy": "shy",
|
||||
// "shyyy": "shy",
|
||||
// },
|
||||
// "shy*": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "sh",
|
||||
// "she": "sh",
|
||||
// "shy": "shy",
|
||||
// "shyyy": "shyyy",
|
||||
// },
|
||||
// "shy+": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "",
|
||||
// "she": "",
|
||||
// "shy": "shy",
|
||||
// "shyyy": "shyyy",
|
||||
// },
|
||||
// "s?hy": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "",
|
||||
// "she": "",
|
||||
// "shy": "shy",
|
||||
// "hy": "hy",
|
||||
// },
|
||||
// "s*hy": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "",
|
||||
// "she": "",
|
||||
// "shy": "shy",
|
||||
// "ssshy": "ssshy",
|
||||
// "hy": "hy",
|
||||
// },
|
||||
// "s+hy": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "",
|
||||
// "she": "",
|
||||
// "shy": "shy",
|
||||
// "ssshy": "ssshy",
|
||||
// "hy": "",
|
||||
// },
|
||||
// "sh[xyz]?": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "sh",
|
||||
// "she": "sh",
|
||||
// "shy": "shy",
|
||||
// "shyyy": "shy",
|
||||
// },
|
||||
// "sh[xyz]*": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "sh",
|
||||
// "she": "sh",
|
||||
// "shy": "shy",
|
||||
// "shyyy": "shyyy",
|
||||
// "shyxz": "shyxz",
|
||||
// },
|
||||
// "sh[xyz]+": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "",
|
||||
// "she": "",
|
||||
// "shy": "shy",
|
||||
// "shyyy": "shyyy",
|
||||
// "shyxzy": "shyxzy",
|
||||
// },
|
||||
// "[xyz]?sh": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "sh",
|
||||
// "zsh": "zsh",
|
||||
// "zxyshy": "",
|
||||
// },
|
||||
// "[xyz]*sh": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "sh",
|
||||
// "zsh": "zsh",
|
||||
// "zxyshy": "zxysh",
|
||||
// },
|
||||
// "[xyz]+sh": map[string]string{
|
||||
// "s": "",
|
||||
// "sh": "",
|
||||
// "zsh": "zsh",
|
||||
// "zxyshy": "zxysh",
|
||||
// },
|
||||
// "[0-9]+": map[string]string{
|
||||
// "hello": "",
|
||||
// "hi123": "",
|
||||
// "123": "123",
|
||||
// "123hi": "123",
|
||||
// },
|
||||
// "0x[0-9a-fA-F]+": map[string]string{
|
||||
// "hello": "",
|
||||
// "0xhi123": "",
|
||||
// "0x123": "0x123",
|
||||
// "0xab123ab": "0xab123ab",
|
||||
// "0x123ab": "0x123ab",
|
||||
// },
|
||||
"[a-zA-Z][a-zA-Z0-9]*": map[string]string{
|
||||
"hello": "hello",
|
||||
"hi123": "hi123",
|
||||
"123": "",
|
||||
},
|
||||
"\"[^\"]*\"": map[string]string{
|
||||
"hello": "",
|
||||
"0xhi123": "",
|
||||
"\"hi\"": "\"hi\"",
|
||||
"\"\\\"hi\"": "\"\\\"hi\"",
|
||||
},
|
||||
}
|
||||
m.Conf("debug", "on")
|
||||
Index.Begin(m)
|
||||
for k, s := range seed {
|
||||
Index.Start(m)
|
||||
m.Cmd("train", k)
|
||||
for i, v := range s {
|
||||
if m.Cmd("parse", i) != v {
|
||||
t.Error("train&parse error:", k, i, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Index.Start(m)
|
||||
m.Cmd("train", "[ \n\t]+", "1")
|
||||
m.Cmd("train", "[a-zA-Z][a-zA-Z0-9]*", "2", "2")
|
||||
m.Cmd("train", "0x[0-9]+", "3", "2")
|
||||
m.Cmd("train", "[0-9]+", "3", "2")
|
||||
m.Cmd("train", "\"[^\"]*\"", "4", "2")
|
||||
m.Cmd("train", "'[^']*'", "4", "2")
|
||||
|
||||
lex := Index.Server.(*LEX)
|
||||
for _, v := range lex.seed {
|
||||
t.Log(v.page, v.hash, v.word)
|
||||
}
|
||||
|
||||
m.Cmd("split", "hello 0x2134 \"hi he\" meet\\ you")
|
||||
// m.Cmd("parse", "0x54 nice to meet")
|
||||
// m.Cmd("parse", "737 nice to meet")
|
||||
// m.Cmd("parse", "\"73 u\" nice to meet")
|
||||
// m.Cmd("parse", "'hh h' nice to meet")
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLog(t *testing.T) {
|
||||
m := ctx.Pulse.Spawn(Index)
|
||||
m.Target().Begin(m)
|
||||
m.Sess("log", m)
|
||||
m.Log("error", "what %v", 123)
|
||||
m.Log("debug", "what %v", 123)
|
||||
m.Log("info", "what %v", 123)
|
||||
m.Log("cmd", "what %v", 123)
|
||||
m.Log("begin", "what %v", 123)
|
||||
m.Log("search", "what %v", 123)
|
||||
m.Cmd("log", "search", "what %v", 123)
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package mdb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOpen(t *testing.T) {
|
||||
flag.Parse()
|
||||
args := flag.Args()
|
||||
if len(args) < 2 {
|
||||
t.Fatal("usages: -args source driver [table]")
|
||||
}
|
||||
|
||||
source := "user:word@/book"
|
||||
driver := "mysql"
|
||||
source = args[0]
|
||||
driver = args[1]
|
||||
|
||||
//mysql -u root -p;
|
||||
//create database book;
|
||||
//grant all on book.* to user identified by 'word'
|
||||
|
||||
ctx.Start()
|
||||
ctx.Index.Conf("debug", "off")
|
||||
log.SetOutput(os.Stdout)
|
||||
m := ctx.Pulse.Spawn(Index)
|
||||
|
||||
m.Meta = nil
|
||||
m.Cmd("open", source, driver)
|
||||
|
||||
m.Meta = nil
|
||||
m.Cmd("exec", "insert into program(time, hash, name) values(?, ?, ?)", "1", "2", "3")
|
||||
|
||||
m.Meta = nil
|
||||
m.Cmd("exec", "insert into program(time, hash, name) values(?, ?, ?)", "1", "2", "3")
|
||||
|
||||
m.Meta = nil
|
||||
m.Cmd("exec", "insert into program(time, hash, name) values(?, ?, ?)", "2", "3", "4")
|
||||
|
||||
m.Meta = nil
|
||||
m.Cmd("query", "select time, hash, name from program")
|
||||
|
||||
t.Log()
|
||||
for i, rows := 0, len(m.Meta[m.Meta["append"][0]]); i < rows; i++ {
|
||||
for _, k := range m.Meta["append"] {
|
||||
t.Log(k, m.Meta[k][i])
|
||||
}
|
||||
t.Log()
|
||||
}
|
||||
|
||||
if len(m.Meta["append"]) != 3 || len(m.Meta[m.Meta["append"][0]]) != 2 {
|
||||
t.Error()
|
||||
}
|
||||
|
||||
m.Meta = nil
|
||||
// Index.Exit(m)
|
||||
}
|
@ -2,10 +2,6 @@ package ssh
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"toolkit"
|
||||
)
|
||||
@ -29,7 +25,7 @@ func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool {
|
||||
return true
|
||||
}
|
||||
func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
@ -37,12 +33,10 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
"nnode": &ctx.Cache{Name: "nnode", Value: "0", Help: "节点数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"},
|
||||
"trust": &ctx.Config{Name: "trust", Value: map[string]interface{}{}, Help: "可信主机"},
|
||||
"node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "主机信息"},
|
||||
"node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "节点信息"},
|
||||
"cert": &ctx.Config{Name: "cert", Value: map[string]interface{}{}, Help: "用户信息"},
|
||||
"trust": &ctx.Config{Name: "trust", Value: map[string]interface{}{"fresh": true, "user": true, "up": true}, Help: "可信节点"},
|
||||
"timer": &ctx.Config{Name: "timer", Value: map[string]interface{}{"interval": "10s", "timer": ""}, Help: "断线重连"},
|
||||
|
||||
"cert": &ctx.Config{Name: "cert", Value: map[string]interface{}{}, Help: "用户证书"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init", Help: "启动", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
@ -55,60 +49,273 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
}
|
||||
m.Conf("runtime", "node.route", m.Conf("runtime", "node.name"))
|
||||
m.Conf("runtime", "user.name", m.Conf("runtime", "boot.USER"))
|
||||
m.Conf("runtime", "work.name", m.Conf("runtime", "boot.USER"))
|
||||
return
|
||||
}},
|
||||
"cert": &ctx.Command{Name: "cert [node|user|work [create [args...]]]", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
"node": &ctx.Command{Name: "node [create|delete [name [type module]]]", Help: "节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("ctx.config", "node", "format", "table", "fields", "type", "module", "create_time")
|
||||
return
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
case "create": // 添加节点
|
||||
m.Log("info", "create node %s %s", arg[1], arg[2])
|
||||
m.Confv("node", arg[1], map[string]interface{}{
|
||||
"name": arg[1], "type": arg[2], "module": arg[3],
|
||||
"create_time": m.Time(),
|
||||
})
|
||||
|
||||
case "delete": // 删除节点
|
||||
m.Log("info", "delete node %s %s", arg[1], kit.Formats(m.Conf("node", arg[1])))
|
||||
delete(m.Confm("node"), arg[1])
|
||||
}
|
||||
return
|
||||
}},
|
||||
"cert": &ctx.Command{Name: "cert [node|user|work]", Help: []string{"认证",
|
||||
"node [create|check text|trust node]",
|
||||
"user [create|check text|share role node...|proxy node|trust node]",
|
||||
"work [create node name|check node name]",
|
||||
}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Add("append", "key", "node.cert")
|
||||
m.Add("append", "route", m.Conf("runtime", "node.route"))
|
||||
m.Add("append", "value", m.Conf("runtime", "node.cert"))
|
||||
m.Add("append", "key", "user.cert")
|
||||
m.Add("append", "route", m.Conf("runtime", "user.route"))
|
||||
m.Add("append", "value", m.Conf("runtime", "user.cert"))
|
||||
m.Add("append", "key", "work.name")
|
||||
m.Add("append", "route", m.Conf("runtime", "work.route"))
|
||||
m.Add("append", "value", m.Conf("runtime", "work.name"))
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
case "node": // 节点证书
|
||||
if len(arg) > 1 && arg[1] == "create" {
|
||||
case "node": // 节点认证
|
||||
if len(arg) == 1 {
|
||||
m.Echo(m.Conf("runtime", "node.cert"))
|
||||
break
|
||||
}
|
||||
|
||||
switch arg[1] {
|
||||
case "create": // 创建证书
|
||||
msg := m.Cmd("aaa.rsa", "gen")
|
||||
m.Conf("runtime", "node.cert", msg.Append("certificate"))
|
||||
m.Conf("runtime", "node.key", msg.Append("private"))
|
||||
}
|
||||
m.Echo(m.Conf("runtime", "node.cert"))
|
||||
|
||||
case "user": // 用户证书
|
||||
if len(arg) > 1 && arg[1] == "create" {
|
||||
case "check": // 数字验签
|
||||
if m.Option("node.cert", m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert").Append("meta")); !m.Options("node.cert") {
|
||||
m.Option("node.cert", m.Cmdx("ssh.remote", m.Option("node.route"), "check", "node"))
|
||||
m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert"))
|
||||
}
|
||||
|
||||
if !m.Cmds("aaa.rsa", "verify", m.Option("node.cert"), m.Option("node.sign"), arg[2]) {
|
||||
m.Log("warn", "node error")
|
||||
m.Echo("false")
|
||||
} else {
|
||||
m.Echo("true")
|
||||
}
|
||||
|
||||
case "trust": // 可信节点
|
||||
if m.Confs("trust", arg[2]) {
|
||||
m.Echo("true")
|
||||
|
||||
} else if m.Confs("trust", "user") && m.Conf("runtime", "user.route") == arg[2] {
|
||||
m.Echo("true")
|
||||
|
||||
} else if m.Confs("trust", "up") && strings.HasPrefix(m.Conf("runtime", "node.route"), arg[2]) {
|
||||
m.Echo("true")
|
||||
}
|
||||
}
|
||||
|
||||
case "user": // 用户认证
|
||||
if len(arg) == 1 {
|
||||
m.Echo(m.Conf("runtime", "user.cert"))
|
||||
break
|
||||
}
|
||||
|
||||
switch arg[1] {
|
||||
case "create": // 创建证书
|
||||
msg := m.Cmd("aaa.rsa", "gen")
|
||||
m.Conf("runtime", "user.route", m.Conf("runtime", "node.route"))
|
||||
m.Conf("runtime", "user.cert", msg.Append("certificate"))
|
||||
m.Conf("runtime", "user.key", msg.Append("private"))
|
||||
}
|
||||
m.Echo(m.Conf("runtime", "user.cert"))
|
||||
|
||||
case "work": // 工作证书
|
||||
if len(arg) > 1 && arg[1] == "create" {
|
||||
if name := m.Cmdx("ssh.sh", "node", arg[2], "check", "work", m.Conf("runtime", "user.route"), m.Conf("runtime", "user.cert"), arg[3]); name != "" {
|
||||
case "check": // 数字验签
|
||||
if m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta")); !m.Options("user.cert") {
|
||||
m.Option("user.cert", m.Cmd("ssh.remote", m.Option("user.route"), "check", "user").Append("user.cert"))
|
||||
m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert"))
|
||||
m.Cmd("aaa.auth", "username", m.Option("username"), "userrole", "void")
|
||||
}
|
||||
|
||||
if !m.Options("user.cert") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), arg[2]) {
|
||||
m.Log("warn", "user error")
|
||||
m.Echo("false")
|
||||
} else {
|
||||
m.Echo("true")
|
||||
}
|
||||
|
||||
case "share": // 共享用户
|
||||
for _, route := range arg[3:] {
|
||||
user := m.Cmd("ssh.remote", route, "check", "user")
|
||||
if m.Cmd("aaa.role", arg[2], "user", user.Append("user.name"), "cert", user.Append("user.cert")); arg[2] == "root" && route != m.Conf("runtime", "node.route") {
|
||||
m.Conf("runtime", "user.route", user.Append("user.route"))
|
||||
m.Conf("runtime", "user.name", user.Append("user.name"))
|
||||
m.Conf("runtime", "user.cert", user.Append("user.cert"))
|
||||
m.Conf("runtime", "user.key", "")
|
||||
}
|
||||
}
|
||||
|
||||
case "proxy": // 代理用户
|
||||
if len(arg) == 2 {
|
||||
m.Cmdy("aaa.auth", "proxy")
|
||||
break
|
||||
}
|
||||
if !m.Cmds("aaa.auth", "proxy", arg[2], "session") {
|
||||
m.Cmdy("aaa.sess", "proxy", "proxy", arg[2])
|
||||
}
|
||||
|
||||
case "trust": // 可信代理
|
||||
hash := kit.Hashs("rand", m.Option("text.time", m.Time("stamp")), arg[2])
|
||||
m.Option("user.sign", m.Cmdx("ssh.remote", m.Option("user.route"), "check", "user", arg[2], hash))
|
||||
m.Echo("%s", m.Options("user.sign") && m.Cmds("ssh.check", hash))
|
||||
}
|
||||
|
||||
case "work": // 公有认证
|
||||
if len(arg) == 1 {
|
||||
m.Echo(m.Conf("runtime", "work.name"))
|
||||
break
|
||||
}
|
||||
|
||||
switch arg[1] {
|
||||
case "create": // 创建证书
|
||||
if name := m.Cmdx("ssh.remote", arg[2], "check", "work", arg[3], m.Conf("runtime", "user.route"), m.Conf("runtime", "user.cert")); name != "" {
|
||||
m.Conf("runtime", "work.route", arg[2])
|
||||
m.Conf("runtime", "work.name", name)
|
||||
}
|
||||
}
|
||||
m.Echo(m.Conf("runtime", "work.name"))
|
||||
m.Echo(name)
|
||||
}
|
||||
|
||||
case "check": // 数字验签
|
||||
if m.Option("user.route") != m.Cmdx("ssh.remote", arg[2], "check", "work", arg[3]) {
|
||||
m.Log("warn", "work error")
|
||||
m.Echo("false")
|
||||
} else {
|
||||
m.Echo("true")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"remote": &ctx.Command{Name: "remote auto|dial|listen args...", Help: "远程连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("ctx.config", "node", "format", "table")
|
||||
m.Meta["append"] = []string{"key", "type", "create_time"}
|
||||
"check": &ctx.Command{Name: "check node|user|work", Help: []string{"验签",
|
||||
"node", "user [node text]", "work name [node cert]",
|
||||
}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch arg[0] {
|
||||
case "node": // 节点验签
|
||||
m.Echo(m.Conf("runtime", "node.cert"))
|
||||
|
||||
case "user": // 用户验签
|
||||
if len(arg) == 1 {
|
||||
m.Append("user.cert", m.Conf("runtime", "user.cert"))
|
||||
m.Append("user.name", m.Conf("runtime", "user.name"))
|
||||
m.Append("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route")))
|
||||
} else { // 代理签证
|
||||
if arg[1] == m.Conf("runtime", "node.route") || m.Cmds("aaa.auth", "proxy", arg[1], "session") {
|
||||
m.Echo(m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), arg[2]))
|
||||
}
|
||||
}
|
||||
case "work": // 工作验签
|
||||
if cert := m.Confm("cert", arg[1]); len(arg) == 2 {
|
||||
if cert != nil {
|
||||
m.Echo("%s", cert["user"])
|
||||
}
|
||||
} else { // 工作签证
|
||||
if cert == nil {
|
||||
m.Conf("cert", arg[1], map[string]interface{}{"create_time": m.Time(), "user": arg[2]})
|
||||
} else if cert["user"] != arg[2] {
|
||||
return // 签证失败
|
||||
}
|
||||
m.Echo(arg[1])
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"action": &ctx.Command{Name: "action", Help: "命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
hash := kit.Hashs(
|
||||
m.Option("text.rand"),
|
||||
m.Option("text.time"),
|
||||
m.Option("text.cmd"),
|
||||
m.Option("text.route"),
|
||||
m.Option("node.route"),
|
||||
m.Option("user.route"),
|
||||
m.Option("user.name"),
|
||||
m.Option("work.name"),
|
||||
m.Option("work.route"),
|
||||
)
|
||||
|
||||
// 文本验签
|
||||
if m.Option("text.hash") != hash {
|
||||
m.Echo("text error %s != %s", m.Option("text.hash"), hash)
|
||||
m.Log("warn", "text error")
|
||||
return
|
||||
}
|
||||
|
||||
// 设备验签
|
||||
if !m.Cmds("ssh.cert", "node", "check", hash) {
|
||||
m.Echo("node error of %s", m.Option("node.route"))
|
||||
return
|
||||
}
|
||||
|
||||
// 用户验签
|
||||
m.Option("username", m.Option("user.name"))
|
||||
if !m.Confs("runtime", "user.route") && m.Confs("trust", "fresh") {
|
||||
m.Log("warn", "trust fresh %s", m.Option("node.route"))
|
||||
m.Option("trust", "fresh")
|
||||
|
||||
} else if m.Cmds("ssh.cert", "node", "trust", m.Option("node.route")) {
|
||||
m.Log("warn", "trust node %s", m.Option("node.route"))
|
||||
m.Option("trust", "node")
|
||||
|
||||
} else if m.Options("user.route") && m.Cmds("ssh.cert", "node", "trust", m.Option("user.route")) && m.Cmds("ssh.cert", "user", "trust", m.Option("node.route")) {
|
||||
m.Log("warn", "trust user %s", m.Option("user.route"))
|
||||
m.Option("trust", "user")
|
||||
|
||||
} else if m.Option("username", m.Option("work.name")); m.Options("work.route") && m.Cmds("ssh.cert", "node", "trust", m.Option("work.route")) && m.Cmds("ssh.cert", "work", "check", m.Option("work.route"), m.Option("username")) {
|
||||
m.Log("warn", "trust work %s", m.Option("work.route"))
|
||||
m.Option("trust", "work")
|
||||
|
||||
} else if m.Option("userrole", "void"); m.Confs("trust", "none") {
|
||||
m.Log("warn", "trust none")
|
||||
m.Option("trust", "none")
|
||||
|
||||
} else {
|
||||
m.Log("warn", "user error of %s", m.Option("user.route"))
|
||||
return
|
||||
}
|
||||
m.Log("info", "username: %s", m.Option("username"))
|
||||
|
||||
// 创建会话
|
||||
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
|
||||
|
||||
// 创建空间
|
||||
m.Option("bench", m.Cmdx("aaa.sess", "bench", "select"))
|
||||
|
||||
// 权限检查
|
||||
if !m.Cmds("aaa.work", "right", "remote", arg[0]) {
|
||||
m.Echo("no right %s %s", "remote", arg[0])
|
||||
return
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
m.Cmdm(arg)
|
||||
return
|
||||
}},
|
||||
"remote": &ctx.Command{Name: "remote auto|dial|listen args...", Help: "连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
// 设备证书
|
||||
if !m.Confs("runtime", "node.cert") || !m.Confs("runtime", "node.key") {
|
||||
msg := m.Cmd("aaa.rsa", "gen", "common", m.Confv("runtime", "node"))
|
||||
m.Conf("runtime", "node.cert", msg.Append("certificate"))
|
||||
m.Conf("runtime", "node.key", msg.Append("private"))
|
||||
m.Cmd("ssh.cert", "node", "create")
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
@ -134,7 +341,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
|
||||
case "dial": // 连接主机
|
||||
m.Call(func(nfs *ctx.Message) *ctx.Message {
|
||||
// 断线重连
|
||||
// 删除重连
|
||||
if m.Confs("timer", "timer") {
|
||||
m.Conf("timer", "timer", m.Cmdx("cli.timer", "delete", m.Conf("timer", "timer")))
|
||||
}
|
||||
@ -142,101 +349,82 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
// 注册设备
|
||||
m.Spawn(nfs.Target()).Call(func(node *ctx.Message) *ctx.Message {
|
||||
// 添加网关
|
||||
m.Confv("node", node.Append("node.name"), map[string]interface{}{
|
||||
"module": m.Cap("stream", nfs.Format("target")),
|
||||
"create_time": m.Time(),
|
||||
"type": "master",
|
||||
"name": node.Append("node.name"),
|
||||
m.Cmd("ssh.node", "create", node.Append("node.name"), "master", m.Cap("stream", nfs.Format("target")))
|
||||
|
||||
// 清理回调
|
||||
nfs.Free(func(nfs *ctx.Message) bool {
|
||||
m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", node.Append("node.name")), "delete", "node")
|
||||
m.Cmd("ssh.node", "delete", node.Append("node.name"))
|
||||
m.Cap("stream", "")
|
||||
|
||||
// 断线重连
|
||||
m.Conf("timer", "timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer", "interval"), "context", "ssh", "remote", "redial", arg[1:]))
|
||||
return true
|
||||
})
|
||||
|
||||
// 本机路由
|
||||
m.Conf("runtime", "node.route", node.Append("node.route")+"."+node.Result(0))
|
||||
|
||||
// 本机用户
|
||||
if !m.Confs("runtime", "user.route") {
|
||||
// 用户路由
|
||||
if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") {
|
||||
m.Cmd("ssh.share", "root", m.Conf("runtime", "node.route"))
|
||||
} else if node.Appends("user.route") {
|
||||
m.Cmd("ssh.share", "root", node.Append("user.route"))
|
||||
}
|
||||
}
|
||||
m.Conf("runtime", "user.route", m.Conf("runtime", "node.route"))
|
||||
|
||||
// 网关用户
|
||||
if !node.Appends("user.route") {
|
||||
m.Cmd("ssh.share", node.Append("node.route"), "root", m.Conf("runtime", "node.route"))
|
||||
} else if node.Appends("user.route") && !m.Confs("runtime", "user.route") {
|
||||
m.Cmd("ssh.node", "share", "root", node.Append("user.route"))
|
||||
}
|
||||
|
||||
// 清理主机
|
||||
nfs.Free(func(nfs *ctx.Message) bool {
|
||||
m.Conf("timer", "timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer", "interval"), "context", "ssh", "remote", "redial", arg[1:]))
|
||||
m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", node.Append("node.name")), "delete", "node")
|
||||
m.Log("info", "delete node %s", node.Append("node.name"))
|
||||
delete(m.Confm("node"), node.Append("node.name"))
|
||||
m.Cap("stream", "")
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
}, "send", "recv", "add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"), m.Conf("runtime", "node.cert"))
|
||||
}, "send", "add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"), m.Conf("runtime", "node.cert"))
|
||||
return nil
|
||||
}, "nfs.remote", arg)
|
||||
|
||||
case "recv":
|
||||
switch arg[1] {
|
||||
case "add":
|
||||
// 节点命名
|
||||
name := arg[2]
|
||||
// 命名节点
|
||||
name := arg[1]
|
||||
for node := m.Confm("node", name); node != nil; node = m.Confm("node", name) {
|
||||
name = fmt.Sprintf("%s_%d", arg[2], m.Capi("nnode", 1))
|
||||
name = kit.Format("%s_%s", arg[1], m.Capi("nnode", 1))
|
||||
}
|
||||
|
||||
// 添加节点
|
||||
m.Confv("node", name, map[string]interface{}{
|
||||
"module": m.Format("source"),
|
||||
"create_time": m.Time(),
|
||||
"type": arg[3],
|
||||
"name": name,
|
||||
})
|
||||
m.Cmd("ssh.node", "create", name, arg[2], m.Format("source"))
|
||||
|
||||
// 节点路由
|
||||
m.Append("user.name", m.Conf("runtime", "user.name"))
|
||||
m.Append("user.route", m.Conf("runtime", "user.route"))
|
||||
m.Append("node.route", m.Conf("runtime", "node.route"))
|
||||
m.Append("node.name", m.Conf("runtime", "node.name"))
|
||||
m.Echo(name).Back(m)
|
||||
|
||||
// 清理节点
|
||||
// 清理回调
|
||||
m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool {
|
||||
m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", name), "delete", "node")
|
||||
m.Log("info", "delete node %s", name)
|
||||
delete(m.Confm("node"), name)
|
||||
m.Cmd("ssh.node", "delete", name)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
// 同步信息
|
||||
m.Append("node.name", m.Conf("runtime", "node.name"))
|
||||
m.Append("node.route", m.Conf("runtime", "node.route"))
|
||||
m.Append("user.route", m.Conf("runtime", "user.route"))
|
||||
m.Append("user.name", m.Conf("runtime", "user.name"))
|
||||
m.Echo(name).Back(m)
|
||||
|
||||
default:
|
||||
// 拆分路由
|
||||
if arg[0] == m.Conf("runtime", "node.name") || arg[0] == m.Conf("runtime", "node.route") {
|
||||
arg[0] = ""
|
||||
}
|
||||
arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.route")+".")
|
||||
arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.name")+".")
|
||||
route, names, arg := arg[0], strings.SplitN(arg[0], ".", 2), arg[1:]
|
||||
if len(names) > 1 && names[0] == "" && names[1] != "" {
|
||||
names[0], names[1] = names[1], names[0]
|
||||
}
|
||||
|
||||
// 同步异步
|
||||
sync := !m.Options("remote_code")
|
||||
sync := true
|
||||
switch arg[0] {
|
||||
case "async", "sync":
|
||||
sync, arg = arg[0] == "sync", arg[1:]
|
||||
}
|
||||
|
||||
// 路由转发
|
||||
// 局域路由
|
||||
if arg[0] == m.Conf("runtime", "node.name") || arg[0] == m.Conf("runtime", "node.route") {
|
||||
arg[0] = ""
|
||||
}
|
||||
arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.route")+".")
|
||||
arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.name")+".")
|
||||
|
||||
// 拆分路由
|
||||
route, names, arg := arg[0], strings.SplitN(arg[0], ".", 2), arg[1:]
|
||||
if len(names) > 1 && names[0] == "" && names[1] != "" {
|
||||
names[0], names[1] = names[1], names[0]
|
||||
}
|
||||
|
||||
if rest := kit.Select("", names, 1); names[0] != "" {
|
||||
// 数字签名
|
||||
if !m.Options("remote_code") && arg[0] != "check" {
|
||||
// 数据哈希
|
||||
hash, meta := kit.Hash("rand",
|
||||
m.Option("text.time", m.Time("stamp")),
|
||||
m.Option("text.cmd", strings.Join(arg, " ")),
|
||||
@ -245,369 +433,55 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
m.Option("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route"))),
|
||||
m.Option("user.name", m.Option("username")),
|
||||
m.Option("work.name", m.Conf("runtime", "work.name")),
|
||||
m.Option("work.route", m.Conf("runtime", "work.route")),
|
||||
)
|
||||
m.Option("text.rand", meta[0])
|
||||
|
||||
// 设备签名
|
||||
m.Option("node.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "node.key"), m.Option("text.hash", hash)))
|
||||
|
||||
// 用户签名
|
||||
if m.Options("user.sign") && m.Confs("runtime", "user.key") {
|
||||
m.Option("user.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), m.Option("text.hash", hash)))
|
||||
}
|
||||
}
|
||||
|
||||
// 查找路由
|
||||
ps := []string{}
|
||||
if names[0] == "%" || names[0] == "*" { // 广播命令
|
||||
m.Confm("node", names[0], func(name string, node map[string]interface{}) {
|
||||
if kit.Format(node["type"]) != "master" {
|
||||
m.Find(kit.Format(node["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
|
||||
return m.CopyFuck(sub, "append").CopyFuck(sub, "result").Echo("\n\n")
|
||||
}, "send", rest, arg)
|
||||
ps = append(ps, kit.Format(node["module"]))
|
||||
}
|
||||
})
|
||||
|
||||
} else if m.Confm("node", names[0], func(node map[string]interface{}) { // 单播命令
|
||||
m.Find(kit.Format(node["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
|
||||
return m.Copy(sub, "append").Copy(sub, "result")
|
||||
}, "send", rest, arg)
|
||||
ps = append(ps, kit.Format(node["module"]))
|
||||
|
||||
}) == 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)
|
||||
}) == nil && m.Caps("stream") { // 上报命令
|
||||
rest = strings.Join(names, ".")
|
||||
ps = append(ps, m.Cap("stream"))
|
||||
}
|
||||
if len(ps) == 0 {
|
||||
m.Echo("error: not found %s", names[0]).Back(m)
|
||||
return
|
||||
}
|
||||
|
||||
// 路由转发
|
||||
for _, p := range ps {
|
||||
m.Find(p, true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
|
||||
return m.CopyFuck(sub, "append").CopyFuck(sub, "result").Echo("\n")
|
||||
}, "send", rest, arg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
// 远程回调
|
||||
defer func() { m.Back(m) }()
|
||||
|
||||
// 查看证书
|
||||
switch arg[0] {
|
||||
case "check":
|
||||
switch arg[1] {
|
||||
case "node": // 设备证书
|
||||
m.Echo(m.Conf("runtime", "node.cert"))
|
||||
case "user":
|
||||
if len(arg) == 2 { // 用户证书
|
||||
m.Append("user.cert", m.Conf("runtime", "user.cert"))
|
||||
m.Append("user.name", m.Conf("runtime", "user.name"))
|
||||
m.Append("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route")))
|
||||
} else { // 代理验证
|
||||
if arg[2] == m.Conf("runtime", "node.route") || m.Cmds("aaa.auth", "proxy", arg[2], "session") {
|
||||
m.Echo(m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), arg[3]))
|
||||
}
|
||||
}
|
||||
case "work":
|
||||
if len(arg) == 2 { // 查看
|
||||
if cert := m.Confm("cert", arg[2]); cert != nil {
|
||||
m.Echo("%s", cert["user"])
|
||||
return
|
||||
}
|
||||
|
||||
} else { // 申请
|
||||
if cert := m.Confm("cert", arg[4]); cert != nil {
|
||||
if cert["user"] != arg[2] {
|
||||
return
|
||||
}
|
||||
m.Echo(arg[4])
|
||||
return
|
||||
}
|
||||
|
||||
m.Conf("cert", arg[4], map[string]interface{}{
|
||||
"create_time": m.Time(),
|
||||
"user": arg[2],
|
||||
})
|
||||
m.Echo(arg[4])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if m.Options("remote_code") {
|
||||
// 检查数据
|
||||
hash, _ := kit.Hash(
|
||||
m.Option("text.rand"),
|
||||
m.Option("text.time"),
|
||||
m.Option("text.cmd"),
|
||||
m.Option("text.route"),
|
||||
m.Option("node.route"),
|
||||
m.Option("user.route"),
|
||||
m.Option("user.name"),
|
||||
m.Option("work.name"),
|
||||
)
|
||||
if m.Option("text.hash") != hash {
|
||||
m.Log("warning", "text error")
|
||||
return
|
||||
}
|
||||
|
||||
// 设备证书
|
||||
if m.Option("node.cert", m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert").Append("meta")); !m.Options("node.cert") {
|
||||
m.Option("node.cert", m.Spawn().Cmdx("ssh.remote", m.Option("node.route"), "sync", "check", "node"))
|
||||
m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert"))
|
||||
}
|
||||
// 设备验签
|
||||
if !m.Cmds("aaa.rsa", "verify", m.Option("node.cert"), m.Option("node.sign"), m.Option("text.hash", hash)) {
|
||||
m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert"))
|
||||
m.Log("warning", "node error")
|
||||
m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "node", "delete")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
m.Option("user.name", m.Conf("runtime", "user.name"))
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
case "share": // 设备权限
|
||||
// 默认用户
|
||||
if !m.Confs("runtime", "user.route") {
|
||||
user := m.Spawn().Cmd("ssh.remote", m.Option("user.route"), "sync", "check", "user")
|
||||
m.Conf("runtime", "user.route", user.Append("user.route"))
|
||||
m.Conf("runtime", "user.name", user.Append("user.name"))
|
||||
m.Conf("runtime", "user.cert", user.Append("user.cert"))
|
||||
m.Cmd("aaa.role", "root", "user", user.Append("user.name"))
|
||||
m.Cmd("aaa.auth", "username", user.Append("user.name"), "cert", user.Append("user.cert"))
|
||||
return
|
||||
}
|
||||
|
||||
// 共享用户
|
||||
if !m.Options("remote_code") || (m.Options("user.sign") && m.Conf("runtime", "user.name") == m.Option("user.name")) {
|
||||
if !m.Options("remote_code") || m.Cmds("aaa.rsa", "verify", m.Conf("runtime", "user.cert"), m.Option("user.sign"), m.Option("text.hash")) {
|
||||
for _, v := range arg[2:] {
|
||||
user := m.Spawn().Cmd("ssh.remote", v, "sync", "check", "user")
|
||||
m.Cmd("aaa.user", arg[1], "user", user.Append("user.name"))
|
||||
m.Cmd("aaa.auth", "username", user.Append("user.name"), "cert", user.Append("user.cert"))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 申请权限
|
||||
m.Spawn().Set("option", "remote_code", "").Cmds("ssh.remote", m.Conf("runtime", "user.route"), "sync", "apply", arg[1:])
|
||||
return
|
||||
|
||||
case "apply": // 权限申请
|
||||
for _, v := range arg[2:] {
|
||||
user := m.Spawn().Cmd("ssh.remote", v, "sync", "check", "user")
|
||||
m.Cmd("aaa.auth", "username", user.Append("user.name"), "cert", user.Append("user.cert"))
|
||||
|
||||
sess := m.Cmd("aaa.auth", "username", user.Append("user.name"), "session", "apply").Append("key")
|
||||
if sess == "" {
|
||||
sess = m.Cmdx("aaa.sess", "apply", "username", arg[2])
|
||||
}
|
||||
m.Cmd("aaa.auth", sess, "apply", m.Option("node.route"))
|
||||
m.Cmd("aaa.auth", sess, "share", user.Append("user.route"))
|
||||
}
|
||||
return
|
||||
|
||||
case "login": // 用户代理
|
||||
if !m.Cmds("aaa.auth", "proxy", m.Option("node.route")) {
|
||||
return
|
||||
}
|
||||
|
||||
sess := m.Cmd("aaa.auth", "username", m.Option("user.name"), "session", "proxy").Append("key")
|
||||
if sess == "" {
|
||||
sess = m.Cmdx("aaa.sess", "proxy", "username", m.Option("user.name"))
|
||||
}
|
||||
|
||||
m.Cmd("aaa.auth", sess, "proxy", m.Option("node.route"))
|
||||
m.Echo(sess)
|
||||
return
|
||||
}
|
||||
|
||||
if m.Options("remote_code") {
|
||||
m.Log("info", "username %s", m.Option("work.name"))
|
||||
if m.Option("username", m.Option("work.name")); m.Confs("trust", m.Option("node.route")) {
|
||||
m.Log("info", "skip verify user of node %s", m.Option("node.route"))
|
||||
} else if m.Confs("trust", "up") && strings.HasPrefix(m.Conf("runtime", "node.route"), m.Option("node.route")) {
|
||||
m.Log("info", "skip verify user of up node %s", m.Option("node.route"))
|
||||
} else {
|
||||
// 用户签名
|
||||
hash, _ := kit.Hash("rand", m.Option("text.time", m.Time("stamp")), m.Option("node.route"))
|
||||
if m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta")); !m.Options("user.cert") {
|
||||
m.Option("user.cert", m.Cmd("ssh.remote", m.Option("user.route"), "sync", "check", "user").Append("user.cert"))
|
||||
m.Log("fuck", "user.eert %v", m.Option("user.cert"))
|
||||
m.Log("fuck", "wat %v", m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert")))
|
||||
}
|
||||
m.Option("user.sign", m.Spawn().Cmdx("ssh.remote", m.Option("user.route"), "sync", "check", "user", m.Option("node.route"), hash))
|
||||
|
||||
// 代理验签
|
||||
if !m.Options("user.cert") || !m.Options("user.sign") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), hash) {
|
||||
m.Log("warn", "user error")
|
||||
m.Echo("no right of %s", m.Option("text.route"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 创建会话
|
||||
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
|
||||
|
||||
// 创建空间
|
||||
m.Option("bench", m.Cmdx("aaa.sess", "bench", "select"))
|
||||
|
||||
// 权限检查
|
||||
if !m.Cmds("aaa.work", "right", "remote", arg[0]) {
|
||||
m.Echo("no right %s %s", "remote", arg[0])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
if arg[0] == "check" { // 数字验签
|
||||
m.Cmd(arg)
|
||||
|
||||
} else if m.Options("remote_code") { // 远程调用
|
||||
m.Cmd("action", arg)
|
||||
|
||||
} else { // 本地调用
|
||||
m.Cmdm(arg)
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
||||
"share": &ctx.Command{Name: "share [serve.route] role client.route...", Help: "共享权限", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmd("aaa.auth", "apply").Table(func(node map[string]string) {
|
||||
m.Cmd("aaa.auth", node["key"], "session", "apply").Table(func(sess map[string]string) {
|
||||
m.Cmd("aaa.auth", sess["key"], "username").Table(func(user map[string]string) {
|
||||
m.Add("append", "time", sess["create_time"])
|
||||
m.Add("append", "user", user["meta"])
|
||||
m.Add("append", "node", node["meta"])
|
||||
})
|
||||
})
|
||||
})
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
|
||||
// 本地用户
|
||||
if len(arg) == 2 {
|
||||
m.Option("user.route", arg[1])
|
||||
m.Cmd("ssh.remote", "", "share", arg[1:])
|
||||
return
|
||||
}
|
||||
|
||||
// 远程用户
|
||||
m.Option("user.sign", "yes")
|
||||
m.Cmd("ssh.remote", arg[0], "sync", "share", arg[1:])
|
||||
return
|
||||
}},
|
||||
"proxy": &ctx.Command{Name: "proxy [proxy.route]", Help: "代理节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("aaa.auth", "proxy")
|
||||
return
|
||||
}
|
||||
if !m.Cmds("aaa.auth", "proxy", arg[0], "session") {
|
||||
m.Cmdy("aaa.sess", "proxy", "proxy", arg[0])
|
||||
}
|
||||
return
|
||||
}},
|
||||
"login": &ctx.Command{Name: "login client.route", Help: "用户节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmd("aaa.auth", "login")
|
||||
return
|
||||
}
|
||||
|
||||
if !m.Cmds("ssh.remote", arg[0], "login") {
|
||||
m.Echo("error: ").Echo("login failure")
|
||||
return
|
||||
}
|
||||
|
||||
sess := m.Cmd("aaa.auth", "username", m.Option("username"), "session", "login").Append("key")
|
||||
if sess == "" {
|
||||
sess = m.Cmdx("aaa.sess", "login", "username", m.Option("username"))
|
||||
}
|
||||
|
||||
m.Cmd("aaa.auth", sess, "login", arg[0])
|
||||
m.Echo(sess)
|
||||
return
|
||||
}},
|
||||
|
||||
"sh": &ctx.Command{Name: "sh [[node] name] cmd...", Help: "发送命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("ssh.remote")
|
||||
return
|
||||
}
|
||||
|
||||
if arg[0] == "sub" {
|
||||
m.Confm("node", func(name string, node map[string]interface{}) {
|
||||
if node["type"] == "master" {
|
||||
return
|
||||
}
|
||||
msg := m.Cmd("ssh.remote", name, arg[1:])
|
||||
if len(msg.Meta["append"]) > 0 && !msg.Has("node") {
|
||||
line := len(msg.Meta[msg.Meta["append"][0]])
|
||||
for i := 0; i < line; i++ {
|
||||
msg.Add("append", "node", m.Conf("runtime", "node.route")+"."+name)
|
||||
}
|
||||
msg.Set("result").Table()
|
||||
}
|
||||
m.CopyFuck(msg, "append")
|
||||
m.CopyFuck(msg, "result")
|
||||
return
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if arg[0] == "node" {
|
||||
m.Conf("current", arg[1])
|
||||
arg = arg[2:]
|
||||
} else if m.Confm("node", arg[0]) != nil {
|
||||
m.Conf("current", arg[0])
|
||||
arg = arg[1:]
|
||||
} else {
|
||||
m.Confm("node", func(name string, node map[string]interface{}) bool {
|
||||
if strings.Contains(name, arg[0]) {
|
||||
m.Conf("current", name)
|
||||
arg = arg[1:]
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
msg := m.Cmd("ssh.remote", m.Conf("current"), arg)
|
||||
m.Copy(msg, "append")
|
||||
m.Copy(msg, "result")
|
||||
return
|
||||
}},
|
||||
"cp": &ctx.Command{Name: "cp [[node] name] filename", Help: "发送文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Echo(m.Conf("current"))
|
||||
return
|
||||
}
|
||||
|
||||
if arg[0] == "node" {
|
||||
m.Conf("current", arg[1])
|
||||
arg = arg[2:]
|
||||
} else if m.Confm("node", arg[0]) != nil {
|
||||
m.Conf("current", arg[0])
|
||||
arg = arg[1:]
|
||||
}
|
||||
|
||||
if arg[0] == "save" {
|
||||
buf, e := base64.StdEncoding.DecodeString(m.Option("filebuf"))
|
||||
m.Assert(e)
|
||||
|
||||
f, e := os.OpenFile(path.Join("tmp", m.Option("filename")), os.O_RDWR|os.O_CREATE, 0666)
|
||||
f.WriteAt(buf, int64(m.Optioni("filepos")))
|
||||
return e
|
||||
}
|
||||
|
||||
p := m.Cmdx("nfs.path", arg[0])
|
||||
f, e := os.Open(p)
|
||||
m.Assert(e)
|
||||
s, e := f.Stat()
|
||||
m.Assert(e)
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
for i := int64(0); i < s.Size(); i += 1024 {
|
||||
n, _ := f.ReadAt(buf, i)
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
buf = buf[:n]
|
||||
msg := m.Spawn()
|
||||
msg.Option("filename", arg[0])
|
||||
msg.Option("filesize", s.Size())
|
||||
msg.Option("filepos", i)
|
||||
msg.Option("filebuf", base64.StdEncoding.EncodeToString(buf))
|
||||
msg.Cmd("remote", m.Conf("current"), "cp", "save", arg[0])
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
@ -1,29 +0,0 @@
|
||||
package tcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestOpen(t *testing.T) {
|
||||
flag.Parse()
|
||||
args := flag.Args()
|
||||
if len(args) < 1 {
|
||||
t.Fatal("usages: -args address")
|
||||
}
|
||||
|
||||
address := ":9393"
|
||||
address = args[0]
|
||||
|
||||
//mysql -u root -p;
|
||||
//create database book;
|
||||
//grant all on book.* to user identified by 'word'
|
||||
|
||||
ctx.Start()
|
||||
m := ctx.Pulse.Spawn(Index)
|
||||
|
||||
m.Meta = nil
|
||||
Index.Cmd(m, "listen", address)
|
||||
}
|
@ -643,6 +643,10 @@ func Hash(arg ...interface{}) (string, []string) {
|
||||
h := md5.Sum([]byte(strings.Join(args, "")))
|
||||
return hex.EncodeToString(h[:]), args
|
||||
}
|
||||
func Hashs(arg ...interface{}) string {
|
||||
h, _ := Hash(arg...)
|
||||
return h
|
||||
}
|
||||
|
||||
func Block(root interface{}, args ...interface{}) interface{} {
|
||||
|
||||
|
@ -373,6 +373,12 @@ chat模块提供了信息管理。
|
||||
### 通信框架
|
||||
#### 节点路由
|
||||
#### 节点认证
|
||||
|
||||
- text.hash
|
||||
- node.sign
|
||||
- user.sign
|
||||
- work.name
|
||||
|
||||
#### 节点服务
|
||||
### 存储引擎
|
||||
#### 配置
|
||||
|
Loading…
x
Reference in New Issue
Block a user