config.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "os/user"
  8. "path"
  9. "regexp"
  10. "strconv"
  11. "git.wecise.com/wecise/common/matrix/logger"
  12. "git.wecise.com/wecise/common/matrix/util"
  13. "github.com/atrox/homedir"
  14. "github.com/kevinburke/ssh_config"
  15. "golang.org/x/crypto/ssh"
  16. "gopkg.in/yaml.v2"
  17. )
  18. type Node struct {
  19. Name string `yaml:"name"`
  20. Alias string `yaml:"alias"`
  21. Host string `yaml:"host"`
  22. User string `yaml:"user"`
  23. Port int `yaml:"port"`
  24. KeyPath string `yaml:"keypath"`
  25. Passphrase string `yaml:"passphrase"`
  26. Password string `yaml:"password"`
  27. Commands []*Command `yaml:"commands"`
  28. Children []*Node `yaml:"children"`
  29. Jump []*Node `yaml:"jump"`
  30. }
  31. type Regexp struct {
  32. *regexp.Regexp
  33. }
  34. func (r *Regexp) MarshalJSON() ([]byte, error) {
  35. if r == nil || r.Regexp == nil {
  36. return json.Marshal(nil)
  37. }
  38. return json.Marshal(r.String())
  39. }
  40. func (r *Regexp) MarshalYAML() (interface{}, error) {
  41. if r == nil || r.Regexp == nil {
  42. return nil, nil
  43. }
  44. return r.String(), nil
  45. }
  46. type Matcher struct {
  47. Regexp *Regexp
  48. Output string `yaml:"output"`
  49. Debug string `yaml:"debug"`
  50. }
  51. type Command struct {
  52. Cmd string `yaml:"cmd"`
  53. Password string `yaml:"password"`
  54. Regexps []*Matcher
  55. Endregx *Regexp
  56. }
  57. func (n *Node) String() string {
  58. return n.Name
  59. }
  60. func (n *Node) user() string {
  61. if n.User == "" {
  62. return "root"
  63. }
  64. return n.User
  65. }
  66. func (n *Node) port() int {
  67. if n.Port <= 0 {
  68. return 22
  69. }
  70. return n.Port
  71. }
  72. func (n *Node) password() ssh.AuthMethod {
  73. if n.Password == "" {
  74. return nil
  75. }
  76. return ssh.Password(n.Password)
  77. }
  78. func (n *Node) alias() string {
  79. return n.Alias
  80. }
  81. var (
  82. config []*Node
  83. )
  84. func GetConfig() []*Node {
  85. return config
  86. }
  87. func LoadConfig() error {
  88. b, err := LoadConfigBytes(".sshw", ".sshw.yml", ".sshw.yaml")
  89. if err != nil {
  90. return err
  91. }
  92. var c []*Node
  93. err = yaml.Unmarshal(b, &c)
  94. if err != nil {
  95. return err
  96. }
  97. config = c
  98. return nil
  99. }
  100. func LoadSshConfig() error {
  101. u, err := user.Current()
  102. if err != nil {
  103. logger.Error(util.ErrorWithSourceLine(err))
  104. return nil
  105. }
  106. f, _ := os.Open(path.Join(u.HomeDir, ".ssh/config"))
  107. cfg, _ := ssh_config.Decode(f)
  108. var nc []*Node
  109. for _, host := range cfg.Hosts {
  110. alias := fmt.Sprintf("%s", host.Patterns[0])
  111. hostName, err := cfg.Get(alias, "HostName")
  112. if err != nil {
  113. return err
  114. }
  115. if hostName != "" {
  116. port, _ := cfg.Get(alias, "Port")
  117. if port == "" {
  118. port = "22"
  119. }
  120. var c = new(Node)
  121. c.Name = alias
  122. c.Alias = alias
  123. c.Host = hostName
  124. c.User, _ = cfg.Get(alias, "User")
  125. c.Port, _ = strconv.Atoi(port)
  126. keyPath, _ := cfg.Get(alias, "IdentityFile")
  127. c.KeyPath, _ = homedir.Expand(keyPath)
  128. nc = append(nc, c)
  129. // fmt.Println(c.Alias, c.Host, c.User, c.Port, c.KeyPath)
  130. }
  131. }
  132. config = nc
  133. return nil
  134. }
  135. func LoadConfigBytes(names ...string) ([]byte, error) {
  136. u, err := user.Current()
  137. if err != nil {
  138. return nil, err
  139. }
  140. // homedir
  141. for i := range names {
  142. sshw, err := ioutil.ReadFile(path.Join(u.HomeDir, names[i]))
  143. if err == nil {
  144. return sshw, nil
  145. }
  146. }
  147. // relative
  148. for i := range names {
  149. sshw, err := ioutil.ReadFile(names[i])
  150. if err == nil {
  151. return sshw, nil
  152. }
  153. }
  154. return nil, err
  155. }