config.go 3.2 KB

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