main.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package main
  2. import (
  3. "encoding/base64"
  4. "fmt"
  5. "os"
  6. "os/user"
  7. "regexp"
  8. "strings"
  9. "git.wecise.com/wecise/util/logger"
  10. "git.wecise.com/wecise/util/merrs"
  11. "gopkg.in/yaml.v2"
  12. )
  13. func init() {
  14. logger.SetConsole(true)
  15. logger.SetLevel(logger.TRACE)
  16. logger.SetFormat("yyyy-MM-dd HH:mm:ss.SSS [level] msg", "\n")
  17. }
  18. // 通过命令行参数获取 user:password@host
  19. func uchi() (u, c, h string, i int) {
  20. if len(os.Args) < 2 {
  21. return
  22. }
  23. if msi := regexp.MustCompile(`^([^:]+):(.*)@([^@]*)$`).FindStringSubmatchIndex(os.Args[1]); msi != nil {
  24. u = os.Args[1][msi[2]:msi[3]]
  25. c = "=" + os.Args[1][msi[4]:msi[5]]
  26. h = os.Args[1][msi[6]:msi[7]]
  27. i = 2
  28. return
  29. }
  30. if msi := regexp.MustCompile(`^([^:]+)@([^@]*)$`).FindStringSubmatchIndex(os.Args[1]); msi != nil {
  31. u = os.Args[1][msi[2]:msi[3]]
  32. h = os.Args[1][msi[6]:msi[7]]
  33. i = 2
  34. } else if os.Args[1][0] != '-' && strings.Index(os.Args[1], "=") < 0 {
  35. h = os.Args[1]
  36. i = 2
  37. } else {
  38. i = 1
  39. }
  40. if u == "" {
  41. user, err := user.Current()
  42. if err != nil {
  43. logger.Error(merrs.NewError(err))
  44. return "", "", "", 0
  45. }
  46. u = user.Username
  47. }
  48. if h == "" {
  49. h = "127.0.0.1"
  50. }
  51. return
  52. }
  53. type KV struct{ Key, Val string }
  54. func parseArgs(args []string) (kvs []*KV) {
  55. argk := ""
  56. argv := ""
  57. for _, arg := range args {
  58. if argk != "" {
  59. argv = arg
  60. } else if regexp.MustCompile(`^\-\w+$`).MatchString(arg) {
  61. argk = arg[1:]
  62. continue
  63. } else {
  64. kv := strings.SplitN(arg, "=", 2)
  65. if len(kv) == 2 {
  66. argk = kv[0]
  67. argv = kv[1]
  68. } else {
  69. argk = ""
  70. argv = arg
  71. }
  72. }
  73. kvs = append(kvs, &KV{argk, argv})
  74. argk, argv = "", ""
  75. }
  76. if argk != "" {
  77. kvs = append(kvs, &KV{argk, argv})
  78. }
  79. return
  80. }
  81. func main() {
  82. u, c, h, i := uchi()
  83. if i == 0 {
  84. fmt.Println("usage:")
  85. fmt.Println(" msh user:password@host|p=password|a=passcode [[c=]command [p=password|a=passcode] [x=cmd-end-regexp] [[r=regexp] [o=output|n=outputline]]...]...")
  86. fmt.Println(" a=passcode should be base64 encoded, or use p=password")
  87. fmt.Println(" debug info include: p(progress) a(argments) m(match) 1(all)")
  88. return
  89. }
  90. kvs := parseArgs(os.Args[i:])
  91. if c == "" {
  92. for _, kv := range kvs {
  93. if kv.Key == "a" {
  94. c = kv.Val
  95. if c == "" {
  96. c = "="
  97. }
  98. break
  99. }
  100. if kv.Key == "p" {
  101. c = "=" + kv.Val
  102. break
  103. }
  104. }
  105. }
  106. p := c
  107. if len(p) > 0 && p[0:1] == "=" {
  108. p = p[1:]
  109. } else {
  110. x, e := base64.RawStdEncoding.DecodeString(p)
  111. if e == nil {
  112. p = string(x)
  113. }
  114. // else 不是Base64编码,保持原值
  115. }
  116. // explainArgs key, val
  117. cmds := []*Command{{Cmd: "ssh " + u + ":" + p + "@" + h, Password: c, Regexps: []*Matcher{{Regexp: nil, Output: ""}}, Endregx: regxprompt}}
  118. for _, kv := range kvs {
  119. key, val := kv.Key, kv.Val
  120. switch key {
  121. case "", "cmd", "command", "c":
  122. cmds = append(cmds, &Command{Cmd: val, Password: c, Regexps: []*Matcher{{Regexp: nil, Output: ""}}, Endregx: regxprompt})
  123. case "ry":
  124. re, err := regexp.Compile(val)
  125. if err != nil {
  126. logger.Error("arg", i, merrs.NewError(err))
  127. return
  128. } else {
  129. regxyesno = &Regexp{re}
  130. }
  131. case "rc":
  132. re, err := regexp.Compile(val)
  133. if err != nil {
  134. logger.Error("arg", i, merrs.NewError(err))
  135. return
  136. } else {
  137. regxpassword = &Regexp{re}
  138. }
  139. case "rp":
  140. re, err := regexp.Compile(val)
  141. if err != nil {
  142. logger.Error("arg", i, merrs.NewError(err))
  143. return
  144. } else {
  145. regxprompt = &Regexp{re}
  146. }
  147. case "password", "code", "pass", "p":
  148. cmds[len(cmds)-1].Password = "=" + val
  149. case "passcode", "b64code", "a":
  150. cmds[len(cmds)-1].Password = val
  151. case "re", "r", "regex":
  152. if val == "" {
  153. cmds[len(cmds)-1].Regexps = append(cmds[len(cmds)-1].Regexps, &Matcher{Regexp: nil})
  154. } else {
  155. re, err := regexp.Compile(val)
  156. if err != nil {
  157. logger.Error("arg", i, merrs.NewError(err))
  158. return
  159. } else {
  160. cmds[len(cmds)-1].Regexps = append(cmds[len(cmds)-1].Regexps, &Matcher{Regexp: &Regexp{re}})
  161. }
  162. }
  163. case "x", "end":
  164. if val == "" {
  165. cmds[len(cmds)-1].Endregx = regxprompt
  166. } else {
  167. re, err := regexp.Compile(val)
  168. if err != nil {
  169. logger.Error("arg", i, merrs.NewError(err))
  170. return
  171. } else {
  172. cmds[len(cmds)-1].Endregx = &Regexp{re}
  173. }
  174. }
  175. case "out", "o", "output":
  176. cmds[len(cmds)-1].Regexps[len(cmds[len(cmds)-1].Regexps)-1].Output += val
  177. case "outln", "n", "outputline":
  178. cmds[len(cmds)-1].Regexps[len(cmds[len(cmds)-1].Regexps)-1].Output += val + "\n"
  179. case "debug", "d":
  180. cmds[len(cmds)-1].Regexps[len(cmds[len(cmds)-1].Regexps)-1].Debug += val
  181. }
  182. }
  183. if strings.Index(cmds[0].Regexps[0].Debug, "a") >= 0 || strings.Index(cmds[0].Regexps[0].Debug, "1") >= 0 {
  184. //bs, _ := json.MarshalIndent(cmds, "", " ")
  185. bs, _ := yaml.Marshal(cmds)
  186. logger.Debug("arguments:\n" + string(bs))
  187. }
  188. node := &Node{
  189. Name: "x",
  190. Alias: "x",
  191. Host: h,
  192. User: u,
  193. Port: 22,
  194. KeyPath: "",
  195. Passphrase: "",
  196. Password: p,
  197. Commands: cmds,
  198. Children: []*Node{},
  199. Jump: []*Node{},
  200. }
  201. sshc := NewClient(node)
  202. sshc.Login()
  203. }