ares-ssh-deploy 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +471 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +1 -0
- package/dist/types/index.d.ts +67 -0
- package/dist/utils/childProcess.cjs +1 -0
- package/dist/utils/childProcess.d.cts +103 -0
- package/dist/utils/childProcess.d.mts +103 -0
- package/dist/utils/childProcess.d.ts +103 -0
- package/dist/utils/childProcess.mjs +1 -0
- package/dist/utils/common.cjs +1 -0
- package/dist/utils/common.d.cts +45 -0
- package/dist/utils/common.d.mts +45 -0
- package/dist/utils/common.d.ts +45 -0
- package/dist/utils/common.mjs +1 -0
- package/dist/utils/deploy-linux-bastion.cjs +1 -0
- package/dist/utils/deploy-linux-bastion.d.cts +120 -0
- package/dist/utils/deploy-linux-bastion.d.mts +120 -0
- package/dist/utils/deploy-linux-bastion.d.ts +120 -0
- package/dist/utils/deploy-linux-bastion.mjs +1 -0
- package/dist/utils/deploy-windows-server.cjs +1 -0
- package/dist/utils/deploy-windows-server.d.cts +66 -0
- package/dist/utils/deploy-windows-server.d.mts +66 -0
- package/dist/utils/deploy-windows-server.d.ts +66 -0
- package/dist/utils/deploy-windows-server.mjs +1 -0
- package/dist/utils/logger.cjs +1 -0
- package/dist/utils/logger.d.cts +5 -0
- package/dist/utils/logger.d.mts +5 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.mjs +1 -0
- package/dist/utils/ssh.cjs +1 -0
- package/dist/utils/ssh.d.cts +226 -0
- package/dist/utils/ssh.d.mts +226 -0
- package/dist/utils/ssh.d.ts +226 -0
- package/dist/utils/ssh.mjs +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { NodeSSH, SSHExecCommandResponse, SSHExecCommandOptions } from 'node-ssh';
|
|
3
|
+
import { Duplex, Writable, Readable } from 'stream';
|
|
4
|
+
|
|
5
|
+
type ChannelType = "session" | "sftp" | "direct-tcpip" | "direct-streamlocal@openssh.com";
|
|
6
|
+
|
|
7
|
+
type ChannelSubType = "exec" | "shell";
|
|
8
|
+
|
|
9
|
+
interface Channel extends Duplex {
|
|
10
|
+
/** Standard input for the Channel. */
|
|
11
|
+
stdin: this;
|
|
12
|
+
/** Standard output for the Channel. */
|
|
13
|
+
stdout: this;
|
|
14
|
+
/** Standard error for the Channel. */
|
|
15
|
+
stderr: Writable | Readable;
|
|
16
|
+
/** Indicates whether this is a server or client channel. */
|
|
17
|
+
server: boolean;
|
|
18
|
+
/** The channel type, usually "session". */
|
|
19
|
+
type: ChannelType;
|
|
20
|
+
/** The channel subtype, usually "exec", "shell", or undefined. */
|
|
21
|
+
subtype?: ChannelSubType;
|
|
22
|
+
incoming: unknown;
|
|
23
|
+
outgoing: unknown;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sends EOF to the remote side.
|
|
27
|
+
*/
|
|
28
|
+
eof(): void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Closes the channel on both sides.
|
|
32
|
+
*/
|
|
33
|
+
close(...args: any[]): void;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Shuts down the channel on this side.
|
|
37
|
+
*/
|
|
38
|
+
destroy(): this;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Session type-specific methods
|
|
42
|
+
*/
|
|
43
|
+
setWindow(rows: number, cols: number, height: number, width: number): void;
|
|
44
|
+
signal(signalName: string): void;
|
|
45
|
+
exit(status: number): void;
|
|
46
|
+
exit(signalName: string, coreDumped?: boolean, msg?: string): void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Emitted once the channel is completely closed on both the client and the server.
|
|
50
|
+
*/
|
|
51
|
+
on(event: "close", listener: () => void): this;
|
|
52
|
+
on(event: "eof", listener: () => void): this;
|
|
53
|
+
on(event: "end", listener: () => void): this;
|
|
54
|
+
on(event: string | symbol, listener: Function): this;
|
|
55
|
+
once(event: "close", listener: () => void): this;
|
|
56
|
+
once(event: "eof", listener: () => void): this;
|
|
57
|
+
once(event: "end", listener: () => void): this;
|
|
58
|
+
once(event: string | symbol, listener: Function): this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @author: ares
|
|
63
|
+
* @date: 2025/8/28 上午9:15
|
|
64
|
+
* @description: SSH连接远程服务器
|
|
65
|
+
* @param config
|
|
66
|
+
* @returns {Promise<NodeSSH>}
|
|
67
|
+
*/
|
|
68
|
+
declare function getSSHClient(config: SSHClientConfig): Promise<NodeSSH>;
|
|
69
|
+
/**
|
|
70
|
+
* @author: ares
|
|
71
|
+
* @date: 2025/8/28 上午9:16
|
|
72
|
+
* @description: SSH连接堡垒机
|
|
73
|
+
* @param config
|
|
74
|
+
* @returns {Promise<NodeSSH>}
|
|
75
|
+
*/
|
|
76
|
+
declare function getBastionSSHClient(config: SSHClientConfig): Promise<NodeSSH>;
|
|
77
|
+
/**
|
|
78
|
+
* @author: ares
|
|
79
|
+
* @date: 2025/8/28 上午9:21
|
|
80
|
+
* @description: 通过堡垒机与内部服务器建立隧道
|
|
81
|
+
* @param bastionSSHClient
|
|
82
|
+
* @param config
|
|
83
|
+
* @returns {Promise<Channel>}
|
|
84
|
+
*/
|
|
85
|
+
declare function getBastionChannel(bastionSSHClient: NodeSSH, config: BastionChannelConfig): Promise<Channel>;
|
|
86
|
+
/**
|
|
87
|
+
* @author: ares
|
|
88
|
+
* @date: 2025/8/28 上午9:25
|
|
89
|
+
* @description: 通过堡垒机隧道与内部服务器建立SSH连接
|
|
90
|
+
* @param channel
|
|
91
|
+
* @param config
|
|
92
|
+
* @returns {Promise<NodeSSH>}
|
|
93
|
+
*/
|
|
94
|
+
declare function getIntraServerSSHClient(channel: Channel, config: IntraServerSSHClientConfig): Promise<NodeSSH>;
|
|
95
|
+
/**
|
|
96
|
+
* @author: ares
|
|
97
|
+
* @date: 2025/8/28 上午9:29
|
|
98
|
+
* @description: 在堡垒机内部服务器上执行命令
|
|
99
|
+
* @param bastionSSHClient
|
|
100
|
+
* @param channelConfig
|
|
101
|
+
* @param intraServerConfig
|
|
102
|
+
* @param command
|
|
103
|
+
* @param callback
|
|
104
|
+
* @returns {Promise<SSHExecCommandResponse>}
|
|
105
|
+
*/
|
|
106
|
+
declare function execIntraServerCommand(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, command: string, callback?: any): Promise<SSHExecCommandResponse>;
|
|
107
|
+
/**
|
|
108
|
+
* @author: ares
|
|
109
|
+
* @date: 2025/8/28 上午9:35
|
|
110
|
+
* @description: 上传本地目录到堡垒机内部服务器
|
|
111
|
+
* @param bastionSSHClient
|
|
112
|
+
* @param channelConfig
|
|
113
|
+
* @param intraServerConfig
|
|
114
|
+
* @param config
|
|
115
|
+
* @returns {Promise<void>}
|
|
116
|
+
*/
|
|
117
|
+
declare function putDirectoryToIntraServer(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, config: UploadDownloadConfig): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* @author: ares
|
|
120
|
+
* @date: 2025/8/29 上午9:45
|
|
121
|
+
* @description: 从堡垒机内部服务器下载目录到本地目录
|
|
122
|
+
* @param bastionSSHClient
|
|
123
|
+
* @param channelConfig
|
|
124
|
+
* @param intraServerConfig
|
|
125
|
+
* @param config
|
|
126
|
+
* @returns {Promise<void>}
|
|
127
|
+
*/
|
|
128
|
+
declare function getDirectoryFromIntraServer(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, config: UploadDownloadConfig): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* @author: ares
|
|
131
|
+
* @date: 2025/8/28 上午10:50
|
|
132
|
+
* @description: 在堡垒机内部服务器上创建目录
|
|
133
|
+
* @param bastionSSHClient
|
|
134
|
+
* @param channelConfig
|
|
135
|
+
* @param intraServerConfig
|
|
136
|
+
* @param config
|
|
137
|
+
* @returns {Promise<void>}
|
|
138
|
+
*/
|
|
139
|
+
declare function makeDirectoryOnIntraServer(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, config: MakeDirectoryConfig): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* @author: ares
|
|
142
|
+
* @date: 2025/8/28 上午9:29
|
|
143
|
+
* @description: 在远程服务器上执行命令
|
|
144
|
+
* @param ssh
|
|
145
|
+
* @param command
|
|
146
|
+
* @param commandOptions
|
|
147
|
+
* @param callback
|
|
148
|
+
* @returns {Promise<void>}
|
|
149
|
+
*/
|
|
150
|
+
declare function execRemoteServerCommand(ssh: NodeSSH, command: string, commandOptions?: SSHExecCommandOptions, callback?: any): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* @author: ares
|
|
153
|
+
* @date: 2025/8/28 上午9:35
|
|
154
|
+
* @description: 上传本地目录到远程服务器
|
|
155
|
+
* @param ssh
|
|
156
|
+
* @param config
|
|
157
|
+
* @returns {Promise<void>}
|
|
158
|
+
*/
|
|
159
|
+
declare function putDirectoryToRemoteServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* @author: ares
|
|
162
|
+
* @date: 2025/8/29 上午9:45
|
|
163
|
+
* @description: 从远程服务器下载目录到本地目录
|
|
164
|
+
* @param ssh
|
|
165
|
+
* @param config
|
|
166
|
+
* @returns {Promise<void>}
|
|
167
|
+
*/
|
|
168
|
+
declare function getDirectoryFromRemoteServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* @author: ares
|
|
171
|
+
* @date: 2025/8/28 上午10:50
|
|
172
|
+
* @description: 在远程服务器上创建目录
|
|
173
|
+
* @param ssh
|
|
174
|
+
* @param config
|
|
175
|
+
* @returns {Promise<void>}
|
|
176
|
+
*/
|
|
177
|
+
declare function makeDirectoryOnRemoteServer(ssh: NodeSSH, config: MakeDirectoryConfig): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* @author: ares
|
|
180
|
+
* @date: 2025/8/28 上午9:29
|
|
181
|
+
* @description: 在远程windowServer上执行命令
|
|
182
|
+
* @param ssh
|
|
183
|
+
* @param command
|
|
184
|
+
* @param commandOptions
|
|
185
|
+
* @param callback
|
|
186
|
+
* @returns {Promise<SSHExecCommandResponse>}
|
|
187
|
+
*/
|
|
188
|
+
declare function execRemoteWindowServerCommand(ssh: NodeSSH, command: string, commandOptions?: SSHExecCommandOptions, callback?: any): Promise<SSHExecCommandResponse>;
|
|
189
|
+
/**
|
|
190
|
+
* @author: ares
|
|
191
|
+
* @date: 2025/8/28 上午9:35
|
|
192
|
+
* @description: 上传本地目录到远程windowServer
|
|
193
|
+
* @param ssh
|
|
194
|
+
* @param config
|
|
195
|
+
* @returns {Promise<void>}
|
|
196
|
+
*/
|
|
197
|
+
declare function putDirectoryToRemoteWindowServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* @author: ares
|
|
200
|
+
* @date: 2025/8/29 上午9:45
|
|
201
|
+
* @description: 从远程windowServer下载目录到本地目录
|
|
202
|
+
* @param ssh
|
|
203
|
+
* @param config
|
|
204
|
+
* @returns {Promise<void>}
|
|
205
|
+
*/
|
|
206
|
+
declare function getDirectoryFromRemoteWindowServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
207
|
+
/**
|
|
208
|
+
* @author: ares
|
|
209
|
+
* @date: 2025/8/28 上午10:50
|
|
210
|
+
* @description: 在远程windowServer上创建目录
|
|
211
|
+
* @param ssh
|
|
212
|
+
* @param config
|
|
213
|
+
* @returns {Promise<void>}
|
|
214
|
+
*/
|
|
215
|
+
declare function makeDirectoryOnRemoteWindowServer(ssh: NodeSSH, config: MakeDirectoryConfig): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* @author: ares
|
|
218
|
+
* @date: 2025/9/1 下午2:25
|
|
219
|
+
* @description: 在远程windowServer上清空目录
|
|
220
|
+
* @param targetSSH
|
|
221
|
+
* @param path
|
|
222
|
+
* @returns {Promise<void>}
|
|
223
|
+
*/
|
|
224
|
+
declare function clearRemoteWindowServerDir(targetSSH: NodeSSH, path: string): Promise<void>;
|
|
225
|
+
|
|
226
|
+
export { clearRemoteWindowServerDir, execIntraServerCommand, execRemoteServerCommand, execRemoteWindowServerCommand, getBastionChannel, getBastionSSHClient, getDirectoryFromIntraServer, getDirectoryFromRemoteServer, getDirectoryFromRemoteWindowServer, getIntraServerSSHClient, getSSHClient, makeDirectoryOnIntraServer, makeDirectoryOnRemoteServer, makeDirectoryOnRemoteWindowServer, putDirectoryToIntraServer, putDirectoryToRemoteServer, putDirectoryToRemoteWindowServer };
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { NodeSSH, SSHExecCommandResponse, SSHExecCommandOptions } from 'node-ssh';
|
|
3
|
+
import { Duplex, Writable, Readable } from 'stream';
|
|
4
|
+
|
|
5
|
+
type ChannelType = "session" | "sftp" | "direct-tcpip" | "direct-streamlocal@openssh.com";
|
|
6
|
+
|
|
7
|
+
type ChannelSubType = "exec" | "shell";
|
|
8
|
+
|
|
9
|
+
interface Channel extends Duplex {
|
|
10
|
+
/** Standard input for the Channel. */
|
|
11
|
+
stdin: this;
|
|
12
|
+
/** Standard output for the Channel. */
|
|
13
|
+
stdout: this;
|
|
14
|
+
/** Standard error for the Channel. */
|
|
15
|
+
stderr: Writable | Readable;
|
|
16
|
+
/** Indicates whether this is a server or client channel. */
|
|
17
|
+
server: boolean;
|
|
18
|
+
/** The channel type, usually "session". */
|
|
19
|
+
type: ChannelType;
|
|
20
|
+
/** The channel subtype, usually "exec", "shell", or undefined. */
|
|
21
|
+
subtype?: ChannelSubType;
|
|
22
|
+
incoming: unknown;
|
|
23
|
+
outgoing: unknown;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sends EOF to the remote side.
|
|
27
|
+
*/
|
|
28
|
+
eof(): void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Closes the channel on both sides.
|
|
32
|
+
*/
|
|
33
|
+
close(...args: any[]): void;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Shuts down the channel on this side.
|
|
37
|
+
*/
|
|
38
|
+
destroy(): this;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Session type-specific methods
|
|
42
|
+
*/
|
|
43
|
+
setWindow(rows: number, cols: number, height: number, width: number): void;
|
|
44
|
+
signal(signalName: string): void;
|
|
45
|
+
exit(status: number): void;
|
|
46
|
+
exit(signalName: string, coreDumped?: boolean, msg?: string): void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Emitted once the channel is completely closed on both the client and the server.
|
|
50
|
+
*/
|
|
51
|
+
on(event: "close", listener: () => void): this;
|
|
52
|
+
on(event: "eof", listener: () => void): this;
|
|
53
|
+
on(event: "end", listener: () => void): this;
|
|
54
|
+
on(event: string | symbol, listener: Function): this;
|
|
55
|
+
once(event: "close", listener: () => void): this;
|
|
56
|
+
once(event: "eof", listener: () => void): this;
|
|
57
|
+
once(event: "end", listener: () => void): this;
|
|
58
|
+
once(event: string | symbol, listener: Function): this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @author: ares
|
|
63
|
+
* @date: 2025/8/28 上午9:15
|
|
64
|
+
* @description: SSH连接远程服务器
|
|
65
|
+
* @param config
|
|
66
|
+
* @returns {Promise<NodeSSH>}
|
|
67
|
+
*/
|
|
68
|
+
declare function getSSHClient(config: SSHClientConfig): Promise<NodeSSH>;
|
|
69
|
+
/**
|
|
70
|
+
* @author: ares
|
|
71
|
+
* @date: 2025/8/28 上午9:16
|
|
72
|
+
* @description: SSH连接堡垒机
|
|
73
|
+
* @param config
|
|
74
|
+
* @returns {Promise<NodeSSH>}
|
|
75
|
+
*/
|
|
76
|
+
declare function getBastionSSHClient(config: SSHClientConfig): Promise<NodeSSH>;
|
|
77
|
+
/**
|
|
78
|
+
* @author: ares
|
|
79
|
+
* @date: 2025/8/28 上午9:21
|
|
80
|
+
* @description: 通过堡垒机与内部服务器建立隧道
|
|
81
|
+
* @param bastionSSHClient
|
|
82
|
+
* @param config
|
|
83
|
+
* @returns {Promise<Channel>}
|
|
84
|
+
*/
|
|
85
|
+
declare function getBastionChannel(bastionSSHClient: NodeSSH, config: BastionChannelConfig): Promise<Channel>;
|
|
86
|
+
/**
|
|
87
|
+
* @author: ares
|
|
88
|
+
* @date: 2025/8/28 上午9:25
|
|
89
|
+
* @description: 通过堡垒机隧道与内部服务器建立SSH连接
|
|
90
|
+
* @param channel
|
|
91
|
+
* @param config
|
|
92
|
+
* @returns {Promise<NodeSSH>}
|
|
93
|
+
*/
|
|
94
|
+
declare function getIntraServerSSHClient(channel: Channel, config: IntraServerSSHClientConfig): Promise<NodeSSH>;
|
|
95
|
+
/**
|
|
96
|
+
* @author: ares
|
|
97
|
+
* @date: 2025/8/28 上午9:29
|
|
98
|
+
* @description: 在堡垒机内部服务器上执行命令
|
|
99
|
+
* @param bastionSSHClient
|
|
100
|
+
* @param channelConfig
|
|
101
|
+
* @param intraServerConfig
|
|
102
|
+
* @param command
|
|
103
|
+
* @param callback
|
|
104
|
+
* @returns {Promise<SSHExecCommandResponse>}
|
|
105
|
+
*/
|
|
106
|
+
declare function execIntraServerCommand(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, command: string, callback?: any): Promise<SSHExecCommandResponse>;
|
|
107
|
+
/**
|
|
108
|
+
* @author: ares
|
|
109
|
+
* @date: 2025/8/28 上午9:35
|
|
110
|
+
* @description: 上传本地目录到堡垒机内部服务器
|
|
111
|
+
* @param bastionSSHClient
|
|
112
|
+
* @param channelConfig
|
|
113
|
+
* @param intraServerConfig
|
|
114
|
+
* @param config
|
|
115
|
+
* @returns {Promise<void>}
|
|
116
|
+
*/
|
|
117
|
+
declare function putDirectoryToIntraServer(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, config: UploadDownloadConfig): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* @author: ares
|
|
120
|
+
* @date: 2025/8/29 上午9:45
|
|
121
|
+
* @description: 从堡垒机内部服务器下载目录到本地目录
|
|
122
|
+
* @param bastionSSHClient
|
|
123
|
+
* @param channelConfig
|
|
124
|
+
* @param intraServerConfig
|
|
125
|
+
* @param config
|
|
126
|
+
* @returns {Promise<void>}
|
|
127
|
+
*/
|
|
128
|
+
declare function getDirectoryFromIntraServer(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, config: UploadDownloadConfig): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* @author: ares
|
|
131
|
+
* @date: 2025/8/28 上午10:50
|
|
132
|
+
* @description: 在堡垒机内部服务器上创建目录
|
|
133
|
+
* @param bastionSSHClient
|
|
134
|
+
* @param channelConfig
|
|
135
|
+
* @param intraServerConfig
|
|
136
|
+
* @param config
|
|
137
|
+
* @returns {Promise<void>}
|
|
138
|
+
*/
|
|
139
|
+
declare function makeDirectoryOnIntraServer(bastionSSHClient: NodeSSH, channelConfig: BastionChannelConfig, intraServerConfig: IntraServerSSHClientConfig, config: MakeDirectoryConfig): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* @author: ares
|
|
142
|
+
* @date: 2025/8/28 上午9:29
|
|
143
|
+
* @description: 在远程服务器上执行命令
|
|
144
|
+
* @param ssh
|
|
145
|
+
* @param command
|
|
146
|
+
* @param commandOptions
|
|
147
|
+
* @param callback
|
|
148
|
+
* @returns {Promise<void>}
|
|
149
|
+
*/
|
|
150
|
+
declare function execRemoteServerCommand(ssh: NodeSSH, command: string, commandOptions?: SSHExecCommandOptions, callback?: any): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* @author: ares
|
|
153
|
+
* @date: 2025/8/28 上午9:35
|
|
154
|
+
* @description: 上传本地目录到远程服务器
|
|
155
|
+
* @param ssh
|
|
156
|
+
* @param config
|
|
157
|
+
* @returns {Promise<void>}
|
|
158
|
+
*/
|
|
159
|
+
declare function putDirectoryToRemoteServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* @author: ares
|
|
162
|
+
* @date: 2025/8/29 上午9:45
|
|
163
|
+
* @description: 从远程服务器下载目录到本地目录
|
|
164
|
+
* @param ssh
|
|
165
|
+
* @param config
|
|
166
|
+
* @returns {Promise<void>}
|
|
167
|
+
*/
|
|
168
|
+
declare function getDirectoryFromRemoteServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* @author: ares
|
|
171
|
+
* @date: 2025/8/28 上午10:50
|
|
172
|
+
* @description: 在远程服务器上创建目录
|
|
173
|
+
* @param ssh
|
|
174
|
+
* @param config
|
|
175
|
+
* @returns {Promise<void>}
|
|
176
|
+
*/
|
|
177
|
+
declare function makeDirectoryOnRemoteServer(ssh: NodeSSH, config: MakeDirectoryConfig): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* @author: ares
|
|
180
|
+
* @date: 2025/8/28 上午9:29
|
|
181
|
+
* @description: 在远程windowServer上执行命令
|
|
182
|
+
* @param ssh
|
|
183
|
+
* @param command
|
|
184
|
+
* @param commandOptions
|
|
185
|
+
* @param callback
|
|
186
|
+
* @returns {Promise<SSHExecCommandResponse>}
|
|
187
|
+
*/
|
|
188
|
+
declare function execRemoteWindowServerCommand(ssh: NodeSSH, command: string, commandOptions?: SSHExecCommandOptions, callback?: any): Promise<SSHExecCommandResponse>;
|
|
189
|
+
/**
|
|
190
|
+
* @author: ares
|
|
191
|
+
* @date: 2025/8/28 上午9:35
|
|
192
|
+
* @description: 上传本地目录到远程windowServer
|
|
193
|
+
* @param ssh
|
|
194
|
+
* @param config
|
|
195
|
+
* @returns {Promise<void>}
|
|
196
|
+
*/
|
|
197
|
+
declare function putDirectoryToRemoteWindowServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* @author: ares
|
|
200
|
+
* @date: 2025/8/29 上午9:45
|
|
201
|
+
* @description: 从远程windowServer下载目录到本地目录
|
|
202
|
+
* @param ssh
|
|
203
|
+
* @param config
|
|
204
|
+
* @returns {Promise<void>}
|
|
205
|
+
*/
|
|
206
|
+
declare function getDirectoryFromRemoteWindowServer(ssh: NodeSSH, config: UploadDownloadConfig): Promise<void>;
|
|
207
|
+
/**
|
|
208
|
+
* @author: ares
|
|
209
|
+
* @date: 2025/8/28 上午10:50
|
|
210
|
+
* @description: 在远程windowServer上创建目录
|
|
211
|
+
* @param ssh
|
|
212
|
+
* @param config
|
|
213
|
+
* @returns {Promise<void>}
|
|
214
|
+
*/
|
|
215
|
+
declare function makeDirectoryOnRemoteWindowServer(ssh: NodeSSH, config: MakeDirectoryConfig): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* @author: ares
|
|
218
|
+
* @date: 2025/9/1 下午2:25
|
|
219
|
+
* @description: 在远程windowServer上清空目录
|
|
220
|
+
* @param targetSSH
|
|
221
|
+
* @param path
|
|
222
|
+
* @returns {Promise<void>}
|
|
223
|
+
*/
|
|
224
|
+
declare function clearRemoteWindowServerDir(targetSSH: NodeSSH, path: string): Promise<void>;
|
|
225
|
+
|
|
226
|
+
export { clearRemoteWindowServerDir, execIntraServerCommand, execRemoteServerCommand, execRemoteWindowServerCommand, getBastionChannel, getBastionSSHClient, getDirectoryFromIntraServer, getDirectoryFromRemoteServer, getDirectoryFromRemoteWindowServer, getIntraServerSSHClient, getSSHClient, makeDirectoryOnIntraServer, makeDirectoryOnRemoteServer, makeDirectoryOnRemoteWindowServer, putDirectoryToIntraServer, putDirectoryToRemoteServer, putDirectoryToRemoteWindowServer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import A from"path";import{NodeSSH as B}from"node-ssh";import m from"iconv-lite";import{logger as u}from"./logger.mjs";async function d(e){const{host:t,port:r,username:n,password:o,privateKey:E}=e,i=await new B().connect({host:t,port:Number(r),username:n,password:o,privateKey:E});return i.connection.on("error",c=>{c.code==="ECONNRESET"?u.info("SSH\u8FDE\u63A5\u88AB\u91CD\u7F6E"):u.error("SSH\u53D1\u751F\u5F02\u5E38:",c)}),i.connection.on("end",()=>{u.info("SSH\u8FDE\u63A5\u7ED3\u675F")}),i.connection.on("close",()=>{u.info("SSH\u8FDE\u63A5\u5173\u95ED")}),i}async function y(e){u.info("\u5F00\u59CB\u8FDE\u63A5\u5230\u8FDC\u7A0B\u5821\u5792\u673A...");const t=await d(e);return u.info("\u8FDE\u63A5\u5230\u8FDC\u7A0B\u5821\u5792\u673A\u6210\u529F"),t}async function D(e,t){const{srcIP:r="127.0.0.1",srcPort:n=0,dstIP:o,dstPort:E}=t;u.info("\u5F00\u59CB\u901A\u8FC7\u5821\u5792\u673A\u4E0E\u5185\u90E8\u670D\u52A1\u5668\u5EFA\u7ACB\u96A7\u9053...");const i=await e.forwardOut(r,Number(n),o,Number(E));return u.info("\u901A\u8FC7\u5821\u5792\u673A\u4E0E\u5185\u90E8\u670D\u52A1\u5668\u5EFA\u7ACB\u96A7\u9053\u6210\u529F"),i}async function C(e,t){const{username:r,password:n}=t,o=new B;return u.info("\u5F00\u59CB\u8FDE\u63A5\u5230\u5185\u90E8\u76EE\u6807\u670D\u52A1\u5668..."),await o.connect({sock:e,username:r,password:n}),u.info("\u8FDE\u63A5\u5230\u5185\u90E8\u76EE\u6807\u670D\u52A1\u5668\u6210\u529F"),o}async function S(e,t,r,n,o){const E=await D(e,t),i=await C(E,r);u.info(`\u6267\u884C\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u547D\u4EE4\u3010 ${n} \u3011`);const c=await i.execCommand(n),{stderr:a}=c,s=/\r?\n/,F=c.stdout.split(s);return u.info(`\u6267\u884C\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u547D\u4EE4\u3010 ${n} \u3011\u5B8C\u6210`),a&&u.error("\u6267\u884C\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u547D\u4EE4\u3010 ${command} \u3011\u53D1\u751F\u5F02\u5E38:",a),typeof o=="function"&&await o(F),i.dispose(),u.info("dispose\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u7684SSH"),E.close(),u.info("close\u5821\u5792\u673A\u4E0E\u5185\u90E8\u670D\u52A1\u5668\u5EFA\u7ACB\u7684CHANNEL"),c}async function w(e,t,r,n){const o=await D(e,t),E=await C(o,r);u.info("\u5F00\u59CB\u4E0A\u4F20\u672C\u5730\u76EE\u5F55\u5230\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668...");const{localDir:i,remoteDir:c}=n;await E.putDirectory(i,c,{recursive:!0,concurrency:10,validate:function(a){return A.basename(a).substr(0,1)!=="."},tick:function(a,s,F){F?u.error("\u4E0A\u4F20\u5230\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u5931\u8D25:",`\u672C\u5730\u6587\u4EF6${a}`):u.log(`\u4E0A\u4F20\u5230\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u6210\u529F: \u672C\u5730\u6587\u4EF6${a}`)}}),u.info("\u4E0A\u4F20\u672C\u5730\u76EE\u5F55\u5230\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u5B8C\u6210"),E.dispose(),u.info("dispose\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u7684SSH"),o.close(),u.info("close\u5821\u5792\u673A\u4E0E\u5185\u90E8\u670D\u52A1\u5668\u5EFA\u7ACB\u7684CHANNEL")}async function l(e,t,r,n){const o=await D(e,t),E=await C(o,r);u.info("\u5F00\u59CB\u4ECE\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u4E0B\u8F7D\u76EE\u5F55\u5230\u672C\u5730...");const{localDir:i,remoteDir:c}=n;await E.getDirectory(i,c,{recursive:!0,concurrency:10,validate:function(a){return A.basename(a).substr(0,1)!=="."},tick:function(a,s,F){F?u.error("\u4ECE\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u4E0B\u8F7D\u5931\u8D25:",`\u8FDC\u7A0B\u6587\u4EF6${s}`):u.log(`\u4ECE\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u4E0B\u8F7D\u6210\u529F: \u8FDC\u7A0B\u6587\u4EF6${s}`)}}),u.info("\u4ECE\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u4E0B\u8F7D\u76EE\u5F55\u5230\u672C\u5730\u5B8C\u6210"),E.dispose(),u.info("dispose\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u7684SSH"),o.close(),u.info("close\u5821\u5792\u673A\u4E0E\u5185\u90E8\u670D\u52A1\u5668\u5EFA\u7ACB\u7684CHANNEL")}async function p(e,t,r,n){const o=await D(e,t),E=await C(o,r);u.info("\u5F00\u59CB\u5728\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u4E0A\u521B\u5EFA\u76EE\u5F55...");const{path:i,method:c,givenSftp:a}=n;await E.mkdir(i,c,a),u.info("\u5728\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u4E0A\u521B\u5EFA\u76EE\u5F55\u5B8C\u6210"),E.dispose(),u.info("dispose\u5821\u5792\u673A\u5185\u90E8\u670D\u52A1\u5668\u7684SSH"),o.close(),u.info("close\u5821\u5792\u673A\u4E0E\u5185\u90E8\u670D\u52A1\u5668\u5EFA\u7ACB\u7684CHANNEL")}async function v(e,t,r={},n){u.info(`\u6267\u884C\u547D\u4EE4\u3010 ${t} \u3011`);const o=await e.execCommand(t,{encoding:"utf8",...r}),{stderr:E}=o,i=/\r?\n/,c=o.stdout.split(i);u.info(`\u6267\u884C\u547D\u4EE4\u3010 ${t} \u3011\u5B8C\u6210`),E&&u.error(`\u6267\u884C\u547D\u4EE4 ${t} \u53D1\u751F\u5F02\u5E38`,E),typeof n=="function"&&await n(c)}async function $(e,t){u.info("\u5F00\u59CB\u4E0A\u4F20\u672C\u5730\u76EE\u5F55\u5230\u8FDC\u7A0B\u670D\u52A1\u5668...");const{localDir:r,remoteDir:n}=t;await e.putDirectory(r,n,{recursive:!0,concurrency:10,validate:function(o){return A.basename(o).substr(0,1)!=="."},tick:function(o,E,i){i?u.error("\u4E0A\u4F20\u5931\u8D25:",`\u672C\u5730\u6587\u4EF6${o}`):u.log(`\u4E0A\u4F20\u6210\u529F: \u672C\u5730\u6587\u4EF6${o}`)}}),u.info("\u4E0A\u4F20\u672C\u5730\u76EE\u5F55\u5230\u8FDC\u7A0B\u670D\u52A1\u5668\u5B8C\u6210")}async function g(e,t){u.info("\u5F00\u59CB\u4ECE\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0B\u8F7D\u76EE\u5F55\u5230\u672C\u5730...");const{localDir:r,remoteDir:n}=t;await e.getDirectory(r,n,{recursive:!0,concurrency:10,validate:function(o){return A.basename(o).substr(0,1)!=="."},tick:function(o,E,i){i?u.error("\u4E0B\u8F7D\u5931\u8D25:",`\u8FDC\u7A0B\u6587\u4EF6${E}`):u.log(`\u4E0B\u8F7D\u6210\u529F: \u8FDC\u7A0B\u6587\u4EF6${E}`)}}),u.info("\u4ECE\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0B\u8F7D\u76EE\u5F55\u5230\u672C\u5730\u5B8C\u6210")}async function b(e,t){u.info("\u5F00\u59CB\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0A\u521B\u5EFA\u76EE\u5F55...");const{path:r,method:n,givenSftp:o}=t;await e.mkdir(r,n,o),u.info("\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0A\u521B\u5EFA\u76EE\u5F55\u5B8C\u6210")}async function f(e,t,r={},n){u.info(`\u6267\u884C\u547D\u4EE4\u3010 ${t} \u3011`);const o=await e.execCommand(t,{encoding:"binary",...r}),E=Buffer.isBuffer(o.stdout)?m.decode(o.stdout,"GBK"):o.stdout.toString(),i=Buffer.isBuffer(o.stderr)?m.decode(o.stderr,"GBK"):o.stderr.toString(),c=/\r?\n/,a=E.split(c);return u.info(`\u6267\u884C\u547D\u4EE4\u3010 ${t} \u3011\u5B8C\u6210`),i&&u.error(`\u6267\u884C\u547D\u4EE4 ${t} \u53D1\u751F\u5F02\u5E38`,i),typeof n=="function"&&await n(a),o}async function H(e,t){u.info("\u5F00\u59CB\u4E0A\u4F20\u672C\u5730\u76EE\u5F55\u5230\u8FDC\u7A0B\u670D\u52A1\u5668...");const{localDir:r,remoteDir:n}=t;await e.putDirectory(r,n,{recursive:!0,concurrency:10,validate:function(o){return A.basename(o).substr(0,1)!=="."},tick:function(o,E,i){i?u.error("\u4E0A\u4F20\u5931\u8D25:",`\u672C\u5730\u6587\u4EF6${o}`):u.log(`\u4E0A\u4F20\u6210\u529F: ${o}`)}}),u.info("\u4E0A\u4F20\u672C\u5730\u76EE\u5F55\u5230\u8FDC\u7A0B\u670D\u52A1\u5668\u5B8C\u6210")}async function k(e,t){u.info("\u5F00\u59CB\u4ECE\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0B\u8F7D\u76EE\u5F55\u5230\u672C\u5730...");const{localDir:r,remoteDir:n}=t;await e.getDirectory(r,n,{recursive:!0,concurrency:10,validate:function(o){return A.basename(o).substr(0,1)!=="."},tick:function(o,E,i){i?u.error("\u4E0B\u8F7D\u5931\u8D25:",`\u8FDC\u7A0B\u6587\u4EF6${o}`):u.log(`\u4E0B\u8F7D\u6210\u529F: ${o}`)}}),u.info("\u4ECE\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0B\u8F7D\u76EE\u5F55\u5230\u672C\u5730\u5B8C\u6210")}async function N(e,t){u.info("\u5F00\u59CB\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0A\u521B\u5EFA\u76EE\u5F55...");const{path:r,method:n,givenSftp:o}=t;await e.mkdir(r,n,o),u.info("\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u4E0A\u521B\u5EFA\u76EE\u5F55\u5B8C\u6210")}async function R(e,t){u.info("\u5F00\u59CB\u6E05\u7A7A\u670D\u52A1\u5668\u76EE\u6807\u76EE\u5F55...");const r=`tem${new Date().getTime()}`;await f(e,`mkdir ${t}${r}`),await f(e,`robocopy ${t}${r} ${t} /mir`),await f(e,`rmdir ${t}${r}`),u.info("\u6E05\u7A7A\u670D\u52A1\u5668\u76EE\u6807\u76EE\u5F55\u5B8C\u6210")}export{R as clearRemoteWindowServerDir,S as execIntraServerCommand,v as execRemoteServerCommand,f as execRemoteWindowServerCommand,D as getBastionChannel,y as getBastionSSHClient,l as getDirectoryFromIntraServer,g as getDirectoryFromRemoteServer,k as getDirectoryFromRemoteWindowServer,C as getIntraServerSSHClient,d as getSSHClient,p as makeDirectoryOnIntraServer,b as makeDirectoryOnRemoteServer,N as makeDirectoryOnRemoteWindowServer,w as putDirectoryToIntraServer,$ as putDirectoryToRemoteServer,H as putDirectoryToRemoteWindowServer};
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ares-ssh-deploy",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ssh deploy tools",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/types/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
},
|
|
14
|
+
"./utils/*": "./dist/utils/*"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"deploy:windows-server": "dotenvx run --env-file=.env.windows-server -- node src/utils/deploy-windows-server.js",
|
|
18
|
+
"deploy:linux-aliyun-bastion": "dotenvx run --env-file=.env.linux-aliyun-bastion -- node src/utils/deploy-linux-bastion.js"
|
|
19
|
+
},
|
|
20
|
+
"author": "ares <18292577207@126.com>",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@dotenvx/dotenvx": "^1.49.0",
|
|
24
|
+
"child_process": "^1.0.2",
|
|
25
|
+
"dayjs": "^1.11.15",
|
|
26
|
+
"iconv-lite": "^0.7.0",
|
|
27
|
+
"lodash-es": "^4.17.21",
|
|
28
|
+
"log4js": "^6.9.1",
|
|
29
|
+
"node-ssh": "^13.2.1"
|
|
30
|
+
}
|
|
31
|
+
}
|