forked from tihonovgn/sshsync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsshsync.go
119 lines (106 loc) · 2.65 KB
/
sshsync.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main
import (
"fmt"
"github.com/hnakamur/go-scp"
"github.com/howeyc/gopass"
"golang.org/x/crypto/ssh"
"gopkg.in/yaml.v2"
"os"
"path/filepath"
"strings"
)
type Config struct {
Server struct {
User string `yaml:"user"`
Port int32 `yaml:"port"`
Host string `yaml:"host"`
} `yaml:"server"`
Path struct {
Remote string `yaml:"remote"`
Local string `yaml:"local"`
} `yaml:"path"`
}
func main() {
var cfg Config
readConfig(&cfg)
client, err := connect(cfg)
if err != nil {
print(err.Error())
os.Exit(0)
}
remoteFolderList := findRemoteDirs(client, cfg.Path.Remote)
for _, dir := range remoteFolderList {
remoteFileList := findRemoteFiles(client, dir)
for _, remoteFileName := range remoteFileList {
localFileName := cfg.Path.Local + remoteFileName[len(cfg.Path.Remote):]
if fileNotExists(localFileName) {
testDir := filepath.Dir(localFileName)
if fileNotExists(testDir) {
fmt.Println("Create dir " + testDir)
err = os.MkdirAll(testDir, 0644)
if err != nil {
fmt.Println(err)
}
}
fmt.Println("Copy remote " + remoteFileName + " to local " + localFileName)
err = scp.NewSCP(client).ReceiveFile(remoteFileName, localFileName)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
}
}
}
func readConfig(cfg *Config) {
f, err := os.Open("config.yml")
if err != nil {
fmt.Println(err)
os.Exit(2)
}
defer f.Close()
decoder := yaml.NewDecoder(f)
err = decoder.Decode(cfg)
if err != nil {
fmt.Println(err)
os.Exit(2)
}
//todo тут надо проверить все поля конфига
}
func connect(cfg Config) (*ssh.Client, error){
println("password:")
password, _ := gopass.GetPasswd()
config := &ssh.ClientConfig{
User: cfg.Server.User,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Auth: []ssh.AuthMethod{
ssh.Password(string(password)),
},
}
addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
return ssh.Dial("tcp", addr, config)
}
func findRemoteFiles(client *ssh.Client, dir string) []string {
session, err := client.NewSession()
if err != nil {
panic(err.Error())
}
defer session.Close()
cmd := fmt.Sprintf("find %s -maxdepth 1 -type f", dir)
b, _ := session.CombinedOutput(cmd)
return strings.Fields(string(b))
}
func findRemoteDirs(client *ssh.Client, remoteFolder string) []string {
session, err := client.NewSession()
if err != nil {
panic(err.Error())
}
defer session.Close()
cmd := fmt.Sprintf("find %s -type d", remoteFolder)
b, _ := session.CombinedOutput(cmd)
return strings.Fields(string(b))
}
func fileNotExists(filename string) bool {
_, err := os.Stat(filename)
return err != nil && os.IsNotExist(err)
}