xbot.plugins.ssh 0.1.0__tar.gz

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.
Files changed (44) hide show
  1. xbot.plugins.ssh-0.1.0/LICENSE +24 -0
  2. xbot.plugins.ssh-0.1.0/MANIFEST.in +2 -0
  3. xbot.plugins.ssh-0.1.0/PKG-INFO +274 -0
  4. xbot.plugins.ssh-0.1.0/README.md +128 -0
  5. xbot.plugins.ssh-0.1.0/README.zh.md +128 -0
  6. xbot.plugins.ssh-0.1.0/demo/lib/__init__.py +0 -0
  7. xbot.plugins.ssh-0.1.0/demo/lib/testbed.py +48 -0
  8. xbot.plugins.ssh-0.1.0/demo/lib/testcase.py +15 -0
  9. xbot.plugins.ssh-0.1.0/demo/testcases/__init__.py +0 -0
  10. xbot.plugins.ssh-0.1.0/demo/testcases/tc_sftp.py +99 -0
  11. xbot.plugins.ssh-0.1.0/demo/testcases/tc_ssh.py +73 -0
  12. xbot.plugins.ssh-0.1.0/pyproject.toml +3 -0
  13. xbot.plugins.ssh-0.1.0/requirements.txt +2 -0
  14. xbot.plugins.ssh-0.1.0/setup.cfg +4 -0
  15. xbot.plugins.ssh-0.1.0/setup.py +64 -0
  16. xbot.plugins.ssh-0.1.0/tests/__init__.py +0 -0
  17. xbot.plugins.ssh-0.1.0/tests/run.py +39 -0
  18. xbot.plugins.ssh-0.1.0/tests/test_sftp.py +88 -0
  19. xbot.plugins.ssh-0.1.0/tests/test_ssh.py +99 -0
  20. xbot.plugins.ssh-0.1.0/tests/test_utils.py +18 -0
  21. xbot.plugins.ssh-0.1.0/venv/bin/jp.py +54 -0
  22. xbot.plugins.ssh-0.1.0/venv/bin/rst2html.py +23 -0
  23. xbot.plugins.ssh-0.1.0/venv/bin/rst2html4.py +26 -0
  24. xbot.plugins.ssh-0.1.0/venv/bin/rst2html5.py +34 -0
  25. xbot.plugins.ssh-0.1.0/venv/bin/rst2latex.py +26 -0
  26. xbot.plugins.ssh-0.1.0/venv/bin/rst2man.py +26 -0
  27. xbot.plugins.ssh-0.1.0/venv/bin/rst2odt.py +30 -0
  28. xbot.plugins.ssh-0.1.0/venv/bin/rst2odt_prepstyles.py +67 -0
  29. xbot.plugins.ssh-0.1.0/venv/bin/rst2pseudoxml.py +23 -0
  30. xbot.plugins.ssh-0.1.0/venv/bin/rst2s5.py +24 -0
  31. xbot.plugins.ssh-0.1.0/venv/bin/rst2xetex.py +27 -0
  32. xbot.plugins.ssh-0.1.0/venv/bin/rst2xml.py +23 -0
  33. xbot.plugins.ssh-0.1.0/venv/bin/rstpep2html.py +25 -0
  34. xbot.plugins.ssh-0.1.0/xbot/plugins/ssh/__init__.py +0 -0
  35. xbot.plugins.ssh-0.1.0/xbot/plugins/ssh/errors.py +19 -0
  36. xbot.plugins.ssh-0.1.0/xbot/plugins/ssh/sftp.py +211 -0
  37. xbot.plugins.ssh-0.1.0/xbot/plugins/ssh/ssh.py +309 -0
  38. xbot.plugins.ssh-0.1.0/xbot/plugins/ssh/utils.py +30 -0
  39. xbot.plugins.ssh-0.1.0/xbot/plugins/ssh/version.py +3 -0
  40. xbot.plugins.ssh-0.1.0/xbot.plugins.ssh.egg-info/PKG-INFO +274 -0
  41. xbot.plugins.ssh-0.1.0/xbot.plugins.ssh.egg-info/SOURCES.txt +42 -0
  42. xbot.plugins.ssh-0.1.0/xbot.plugins.ssh.egg-info/dependency_links.txt +1 -0
  43. xbot.plugins.ssh-0.1.0/xbot.plugins.ssh.egg-info/requires.txt +4 -0
  44. xbot.plugins.ssh-0.1.0/xbot.plugins.ssh.egg-info/top_level.txt +6 -0
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2022-2023, zhaowcheng <zhaowcheng@163.com>
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,2 @@
1
+ include requirements.txt
2
+ include README*
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.1
2
+ Name: xbot.plugins.ssh
3
+ Version: 0.1.0
4
+ Summary: SSH library for xbot.framework
5
+ Home-page: https://github.com/zhaowcheng/xbot.plugins.ssh
6
+ Author: zhaowcheng
7
+ Author-email: zhaowcheng@163.com
8
+ License: UNKNOWN
9
+ Project-URL: Homepage, https://github.com/zhaowcheng/xbot.plugins.ssh
10
+ Project-URL: Issues, https://github.com/zhaowcheng/xbot.plugins.ssh/issues
11
+ Platform: UNKNOWN
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.6
16
+ Classifier: Programming Language :: Python :: 3.7
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Requires-Python: >=3.6
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+
26
+ ## Introduction
27
+
28
+ `xbot.plugins.ssh` provides ssh and sftp support for [xbot.framework](https://github.com/zhaowcheng/xbot.framework)
29
+
30
+ ## Installation
31
+
32
+ Install via pip:
33
+
34
+ ```
35
+ pip install xbot.plugins.ssh
36
+ ```
37
+
38
+ ## Getting Started
39
+
40
+ ```python
41
+ import os
42
+ import shutil
43
+
44
+ from xbot.plugins.ssh.ssh import SSHConnection
45
+ from xbot.plugins.ssh.sftp import SFTPConnection
46
+
47
+ # Modify the following information to your own before trying to run.
48
+ host = '192.168.8.8'
49
+ user = 'xbot'
50
+ pwd = 'xbot'
51
+
52
+ # Create ssh connection.
53
+ sshconn = SSHConnection()
54
+ sshconn.connect(host, user, pwd)
55
+
56
+ # Expect the return code of command is 0.
57
+ sshconn.exec('ls -l', expect=0)
58
+
59
+ # Expect the return code of command is 2.
60
+ sshconn.exec('ls /errpath', expect=2)
61
+
62
+ # Expect the output of command contains `username`.
63
+ sshconn.exec('whoami', expect=user)
64
+
65
+ # Don't check the result of command.
66
+ sshconn.exec('ls -l', expect=None)
67
+ sshconn.exec('ls /errpath', expect=None)
68
+
69
+ # Execute command with sudo.
70
+ sshconn.sudo('whoami', expect='root')
71
+
72
+ # Interactive command.
73
+ sshconn.exec("read -p 'input: '", prompts={'input:': 'hello'})
74
+
75
+ # Attributes and methods of SSHCommandResult.
76
+ cmd = 'echo -e "jack 20\ntom 30"'
77
+ result = sshconn.exec(cmd)
78
+ assert str(result) == 'jack 20\ntom 30'
79
+ assert result.rc == 0
80
+ assert result.cmd == cmd
81
+ assert result.getfield('tom', 2) == '30'
82
+ assert result.getcol(2) == ['20', '30']
83
+
84
+ # Create sftp connection.
85
+ sftpconn = SFTPConnection()
86
+ sftpconn.connect(host, user, pwd)
87
+
88
+ # Preparing for sftp testing.
89
+ lhome = os.environ.get('HOME') or os.environ['HOMEPATH']
90
+ lputdir = os.path.join(lhome, 'lputdir')
91
+ lgetdir = os.path.join(lhome, 'lgetdir')
92
+ rputdir = '/tmp/rputgetdir'
93
+ rgetdir = rputdir
94
+ if os.path.exists(lputdir):
95
+ shutil.rmtree(lputdir)
96
+ if sftpconn.exists(rputdir):
97
+ sshconn.exec(f'rm -rf {rputdir}')
98
+ sftpconn.makedirs(rputdir)
99
+ os.makedirs(os.path.join(lputdir, 'dir', 'subdir'))
100
+ os.system('whoami > %s' % os.path.join(lputdir, 'file'))
101
+ os.system('whoami > %s' % os.path.join(lputdir, 'dir', 'subfile'))
102
+
103
+ # Put directory.
104
+ l = os.path.join(lputdir, 'dir')
105
+ sftpconn.putdir(l, rputdir)
106
+ p1 = sftpconn.join(rputdir, 'dir', 'subdir')
107
+ assert sftpconn.exists(p1) == True
108
+ p2 = sftpconn.join(rputdir, 'dir', 'subfile')
109
+ assert sftpconn.exists(p2) == True
110
+
111
+ # Put file.
112
+ l = os.path.join(lputdir, 'file')
113
+ sftpconn.putfile(l, rputdir)
114
+ p1 = sftpconn.join(rputdir, 'file')
115
+ assert sftpconn.exists(p1) == True
116
+ sftpconn.putfile(l, rputdir, 'newfile') # rename
117
+ p2 = sftpconn.join(rputdir, 'newfile')
118
+ assert sftpconn.exists(p2) == True
119
+
120
+ # Get directory.
121
+ r = sftpconn.join(rgetdir, 'dir')
122
+ sftpconn.getdir(r, lgetdir)
123
+ p1 = os.path.join(lgetdir, 'dir', 'subdir')
124
+ assert os.path.exists(p1) == True
125
+ p2 = os.path.join(lgetdir, 'dir', 'subfile')
126
+ assert os.path.exists(p2) == True
127
+
128
+ # Get file.
129
+ r = sftpconn.join(rgetdir, 'file')
130
+ sftpconn.getfile(r, lgetdir)
131
+ p1 = os.path.join(lgetdir, 'file')
132
+ assert os.path.exists(p1) == True
133
+ sftpconn.getfile(r, lgetdir, 'newfile') # rename
134
+ p2 = os.path.join(lgetdir, 'newfile')
135
+ assert os.path.exists(p2) == True
136
+
137
+ # Open file.
138
+ p = sftpconn.join(rputdir, 'file')
139
+ with sftpconn.open(p, 'w') as fp:
140
+ fp.write('xbot')
141
+ with sftpconn.open(p, 'r') as fp:
142
+ assert fp.read().decode('utf-8') == 'xbot'
143
+ ```
144
+
145
+ ## Demo Project
146
+
147
+ Here is a [demo](https://github.com/zhaowcheng/xbot.plugins.ssh/tree/v0.1.0/demo) project showing how to use `xbot.plugins.ssh` in a test project.
148
+
149
+ ***
150
+
151
+ ## 简介
152
+
153
+ `xbot.plugins.ssh` 是为 [xbot.framework](https://github.com/zhaowcheng/xbot.framework) 提供 ssh 和 sftp 支持的插件。
154
+
155
+ ## 安装
156
+
157
+ 使用 pip 安装:
158
+
159
+ ```
160
+ pip install xbot.plugins.ssh
161
+ ```
162
+
163
+ ## 入门
164
+
165
+ ```python
166
+ import os
167
+ import shutil
168
+
169
+ from xbot.plugins.ssh.ssh import SSHConnection
170
+ from xbot.plugins.ssh.sftp import SFTPConnection
171
+
172
+ # Modify the following information to your own before trying to run.
173
+ host = '192.168.8.8'
174
+ user = 'xbot'
175
+ pwd = 'xbot'
176
+
177
+ # Create ssh connection.
178
+ sshconn = SSHConnection()
179
+ sshconn.connect(host, user, pwd)
180
+
181
+ # Expect the return code of command is 0.
182
+ sshconn.exec('ls -l', expect=0)
183
+
184
+ # Expect the return code of command is 2.
185
+ sshconn.exec('ls /errpath', expect=2)
186
+
187
+ # Expect the output of command contains `username`.
188
+ sshconn.exec('whoami', expect=user)
189
+
190
+ # Don't check the result of command.
191
+ sshconn.exec('ls -l', expect=None)
192
+ sshconn.exec('ls /errpath', expect=None)
193
+
194
+ # Execute command with sudo.
195
+ sshconn.sudo('whoami', expect='root')
196
+
197
+ # Interactive command.
198
+ sshconn.exec("read -p 'input: '", prompts={'input:': 'hello'})
199
+
200
+ # Attributes and methods of SSHCommandResult.
201
+ cmd = 'echo -e "jack 20\ntom 30"'
202
+ result = sshconn.exec(cmd)
203
+ assert str(result) == 'jack 20\ntom 30'
204
+ assert result.rc == 0
205
+ assert result.cmd == cmd
206
+ assert result.getfield('tom', 2) == '30'
207
+ assert result.getcol(2) == ['20', '30']
208
+
209
+ # Create sftp connection.
210
+ sftpconn = SFTPConnection()
211
+ sftpconn.connect(host, user, pwd)
212
+
213
+ # Preparing for sftp testing.
214
+ lhome = os.environ.get('HOME') or os.environ['HOMEPATH']
215
+ lputdir = os.path.join(lhome, 'lputdir')
216
+ lgetdir = os.path.join(lhome, 'lgetdir')
217
+ rputdir = '/tmp/rputgetdir'
218
+ rgetdir = rputdir
219
+ if os.path.exists(lputdir):
220
+ shutil.rmtree(lputdir)
221
+ if sftpconn.exists(rputdir):
222
+ sshconn.exec(f'rm -rf {rputdir}')
223
+ sftpconn.makedirs(rputdir)
224
+ os.makedirs(os.path.join(lputdir, 'dir', 'subdir'))
225
+ os.system('whoami > %s' % os.path.join(lputdir, 'file'))
226
+ os.system('whoami > %s' % os.path.join(lputdir, 'dir', 'subfile'))
227
+
228
+ # Put directory.
229
+ l = os.path.join(lputdir, 'dir')
230
+ sftpconn.putdir(l, rputdir)
231
+ p1 = sftpconn.join(rputdir, 'dir', 'subdir')
232
+ assert sftpconn.exists(p1) == True
233
+ p2 = sftpconn.join(rputdir, 'dir', 'subfile')
234
+ assert sftpconn.exists(p2) == True
235
+
236
+ # Put file.
237
+ l = os.path.join(lputdir, 'file')
238
+ sftpconn.putfile(l, rputdir)
239
+ p1 = sftpconn.join(rputdir, 'file')
240
+ assert sftpconn.exists(p1) == True
241
+ sftpconn.putfile(l, rputdir, 'newfile') # rename
242
+ p2 = sftpconn.join(rputdir, 'newfile')
243
+ assert sftpconn.exists(p2) == True
244
+
245
+ # Get directory.
246
+ r = sftpconn.join(rgetdir, 'dir')
247
+ sftpconn.getdir(r, lgetdir)
248
+ p1 = os.path.join(lgetdir, 'dir', 'subdir')
249
+ assert os.path.exists(p1) == True
250
+ p2 = os.path.join(lgetdir, 'dir', 'subfile')
251
+ assert os.path.exists(p2) == True
252
+
253
+ # Get file.
254
+ r = sftpconn.join(rgetdir, 'file')
255
+ sftpconn.getfile(r, lgetdir)
256
+ p1 = os.path.join(lgetdir, 'file')
257
+ assert os.path.exists(p1) == True
258
+ sftpconn.getfile(r, lgetdir, 'newfile') # rename
259
+ p2 = os.path.join(lgetdir, 'newfile')
260
+ assert os.path.exists(p2) == True
261
+
262
+ # Open file.
263
+ p = sftpconn.join(rputdir, 'file')
264
+ with sftpconn.open(p, 'w') as fp:
265
+ fp.write('xbot')
266
+ with sftpconn.open(p, 'r') as fp:
267
+ assert fp.read().decode('utf-8') == 'xbot'
268
+ ```
269
+
270
+ ## 示例项目
271
+
272
+ 展示如何在一个测试项目中使用本插件的示例:[demo](https://github.com/zhaowcheng/xbot.plugins.ssh/tree/v0.1.0/demo)
273
+
274
+
@@ -0,0 +1,128 @@
1
+ <p align="center">
2
+ <br>English | <a href="README.zh.md">中文</a>
3
+ </p>
4
+
5
+ ***
6
+
7
+ ## Introduction
8
+
9
+ `xbot.plugins.ssh` provides ssh and sftp support for [xbot.framework](https://github.com/zhaowcheng/xbot.framework)
10
+
11
+ ## Installation
12
+
13
+ Install via pip:
14
+
15
+ ```
16
+ pip install xbot.plugins.ssh
17
+ ```
18
+
19
+ ## Getting Started
20
+
21
+ ```python
22
+ import os
23
+ import shutil
24
+
25
+ from xbot.plugins.ssh.ssh import SSHConnection
26
+ from xbot.plugins.ssh.sftp import SFTPConnection
27
+
28
+ # Modify the following information to your own before trying to run.
29
+ host = '192.168.8.8'
30
+ user = 'xbot'
31
+ pwd = 'xbot'
32
+
33
+ # Create ssh connection.
34
+ sshconn = SSHConnection()
35
+ sshconn.connect(host, user, pwd)
36
+
37
+ # Expect the return code of command is 0.
38
+ sshconn.exec('ls -l', expect=0)
39
+
40
+ # Expect the return code of command is 2.
41
+ sshconn.exec('ls /errpath', expect=2)
42
+
43
+ # Expect the output of command contains `username`.
44
+ sshconn.exec('whoami', expect=user)
45
+
46
+ # Don't check the result of command.
47
+ sshconn.exec('ls -l', expect=None)
48
+ sshconn.exec('ls /errpath', expect=None)
49
+
50
+ # Execute command with sudo.
51
+ sshconn.sudo('whoami', expect='root')
52
+
53
+ # Interactive command.
54
+ sshconn.exec("read -p 'input: '", prompts={'input:': 'hello'})
55
+
56
+ # Attributes and methods of SSHCommandResult.
57
+ cmd = 'echo -e "jack 20\ntom 30"'
58
+ result = sshconn.exec(cmd)
59
+ assert str(result) == 'jack 20\ntom 30'
60
+ assert result.rc == 0
61
+ assert result.cmd == cmd
62
+ assert result.getfield('tom', 2) == '30'
63
+ assert result.getcol(2) == ['20', '30']
64
+
65
+ # Create sftp connection.
66
+ sftpconn = SFTPConnection()
67
+ sftpconn.connect(host, user, pwd)
68
+
69
+ # Preparing for sftp testing.
70
+ lhome = os.environ.get('HOME') or os.environ['HOMEPATH']
71
+ lputdir = os.path.join(lhome, 'lputdir')
72
+ lgetdir = os.path.join(lhome, 'lgetdir')
73
+ rputdir = '/tmp/rputgetdir'
74
+ rgetdir = rputdir
75
+ if os.path.exists(lputdir):
76
+ shutil.rmtree(lputdir)
77
+ if sftpconn.exists(rputdir):
78
+ sshconn.exec(f'rm -rf {rputdir}')
79
+ sftpconn.makedirs(rputdir)
80
+ os.makedirs(os.path.join(lputdir, 'dir', 'subdir'))
81
+ os.system('whoami > %s' % os.path.join(lputdir, 'file'))
82
+ os.system('whoami > %s' % os.path.join(lputdir, 'dir', 'subfile'))
83
+
84
+ # Put directory.
85
+ l = os.path.join(lputdir, 'dir')
86
+ sftpconn.putdir(l, rputdir)
87
+ p1 = sftpconn.join(rputdir, 'dir', 'subdir')
88
+ assert sftpconn.exists(p1) == True
89
+ p2 = sftpconn.join(rputdir, 'dir', 'subfile')
90
+ assert sftpconn.exists(p2) == True
91
+
92
+ # Put file.
93
+ l = os.path.join(lputdir, 'file')
94
+ sftpconn.putfile(l, rputdir)
95
+ p1 = sftpconn.join(rputdir, 'file')
96
+ assert sftpconn.exists(p1) == True
97
+ sftpconn.putfile(l, rputdir, 'newfile') # rename
98
+ p2 = sftpconn.join(rputdir, 'newfile')
99
+ assert sftpconn.exists(p2) == True
100
+
101
+ # Get directory.
102
+ r = sftpconn.join(rgetdir, 'dir')
103
+ sftpconn.getdir(r, lgetdir)
104
+ p1 = os.path.join(lgetdir, 'dir', 'subdir')
105
+ assert os.path.exists(p1) == True
106
+ p2 = os.path.join(lgetdir, 'dir', 'subfile')
107
+ assert os.path.exists(p2) == True
108
+
109
+ # Get file.
110
+ r = sftpconn.join(rgetdir, 'file')
111
+ sftpconn.getfile(r, lgetdir)
112
+ p1 = os.path.join(lgetdir, 'file')
113
+ assert os.path.exists(p1) == True
114
+ sftpconn.getfile(r, lgetdir, 'newfile') # rename
115
+ p2 = os.path.join(lgetdir, 'newfile')
116
+ assert os.path.exists(p2) == True
117
+
118
+ # Open file.
119
+ p = sftpconn.join(rputdir, 'file')
120
+ with sftpconn.open(p, 'w') as fp:
121
+ fp.write('xbot')
122
+ with sftpconn.open(p, 'r') as fp:
123
+ assert fp.read().decode('utf-8') == 'xbot'
124
+ ```
125
+
126
+ ## Demo Project
127
+
128
+ Here is a [demo](https://github.com/zhaowcheng/xbot.plugins.ssh/tree/master/demo) project showing how to use `xbot.plugins.ssh` in a test project.
@@ -0,0 +1,128 @@
1
+ <p align="center">
2
+ <br>中文 | <a href="README.md">English</a>
3
+ </p>
4
+
5
+ ***
6
+
7
+ ## 简介
8
+
9
+ `xbot.plugins.ssh` 是为 [xbot.framework](https://github.com/zhaowcheng/xbot.framework) 提供 ssh 和 sftp 支持的插件。
10
+
11
+ ## 安装
12
+
13
+ 使用 pip 安装:
14
+
15
+ ```
16
+ pip install xbot.plugins.ssh
17
+ ```
18
+
19
+ ## 入门
20
+
21
+ ```python
22
+ import os
23
+ import shutil
24
+
25
+ from xbot.plugins.ssh.ssh import SSHConnection
26
+ from xbot.plugins.ssh.sftp import SFTPConnection
27
+
28
+ # Modify the following information to your own before trying to run.
29
+ host = '192.168.8.8'
30
+ user = 'xbot'
31
+ pwd = 'xbot'
32
+
33
+ # Create ssh connection.
34
+ sshconn = SSHConnection()
35
+ sshconn.connect(host, user, pwd)
36
+
37
+ # Expect the return code of command is 0.
38
+ sshconn.exec('ls -l', expect=0)
39
+
40
+ # Expect the return code of command is 2.
41
+ sshconn.exec('ls /errpath', expect=2)
42
+
43
+ # Expect the output of command contains `username`.
44
+ sshconn.exec('whoami', expect=user)
45
+
46
+ # Don't check the result of command.
47
+ sshconn.exec('ls -l', expect=None)
48
+ sshconn.exec('ls /errpath', expect=None)
49
+
50
+ # Execute command with sudo.
51
+ sshconn.sudo('whoami', expect='root')
52
+
53
+ # Interactive command.
54
+ sshconn.exec("read -p 'input: '", prompts={'input:': 'hello'})
55
+
56
+ # Attributes and methods of SSHCommandResult.
57
+ cmd = 'echo -e "jack 20\ntom 30"'
58
+ result = sshconn.exec(cmd)
59
+ assert str(result) == 'jack 20\ntom 30'
60
+ assert result.rc == 0
61
+ assert result.cmd == cmd
62
+ assert result.getfield('tom', 2) == '30'
63
+ assert result.getcol(2) == ['20', '30']
64
+
65
+ # Create sftp connection.
66
+ sftpconn = SFTPConnection()
67
+ sftpconn.connect(host, user, pwd)
68
+
69
+ # Preparing for sftp testing.
70
+ lhome = os.environ.get('HOME') or os.environ['HOMEPATH']
71
+ lputdir = os.path.join(lhome, 'lputdir')
72
+ lgetdir = os.path.join(lhome, 'lgetdir')
73
+ rputdir = '/tmp/rputgetdir'
74
+ rgetdir = rputdir
75
+ if os.path.exists(lputdir):
76
+ shutil.rmtree(lputdir)
77
+ if sftpconn.exists(rputdir):
78
+ sshconn.exec(f'rm -rf {rputdir}')
79
+ sftpconn.makedirs(rputdir)
80
+ os.makedirs(os.path.join(lputdir, 'dir', 'subdir'))
81
+ os.system('whoami > %s' % os.path.join(lputdir, 'file'))
82
+ os.system('whoami > %s' % os.path.join(lputdir, 'dir', 'subfile'))
83
+
84
+ # Put directory.
85
+ l = os.path.join(lputdir, 'dir')
86
+ sftpconn.putdir(l, rputdir)
87
+ p1 = sftpconn.join(rputdir, 'dir', 'subdir')
88
+ assert sftpconn.exists(p1) == True
89
+ p2 = sftpconn.join(rputdir, 'dir', 'subfile')
90
+ assert sftpconn.exists(p2) == True
91
+
92
+ # Put file.
93
+ l = os.path.join(lputdir, 'file')
94
+ sftpconn.putfile(l, rputdir)
95
+ p1 = sftpconn.join(rputdir, 'file')
96
+ assert sftpconn.exists(p1) == True
97
+ sftpconn.putfile(l, rputdir, 'newfile') # rename
98
+ p2 = sftpconn.join(rputdir, 'newfile')
99
+ assert sftpconn.exists(p2) == True
100
+
101
+ # Get directory.
102
+ r = sftpconn.join(rgetdir, 'dir')
103
+ sftpconn.getdir(r, lgetdir)
104
+ p1 = os.path.join(lgetdir, 'dir', 'subdir')
105
+ assert os.path.exists(p1) == True
106
+ p2 = os.path.join(lgetdir, 'dir', 'subfile')
107
+ assert os.path.exists(p2) == True
108
+
109
+ # Get file.
110
+ r = sftpconn.join(rgetdir, 'file')
111
+ sftpconn.getfile(r, lgetdir)
112
+ p1 = os.path.join(lgetdir, 'file')
113
+ assert os.path.exists(p1) == True
114
+ sftpconn.getfile(r, lgetdir, 'newfile') # rename
115
+ p2 = os.path.join(lgetdir, 'newfile')
116
+ assert os.path.exists(p2) == True
117
+
118
+ # Open file.
119
+ p = sftpconn.join(rputdir, 'file')
120
+ with sftpconn.open(p, 'w') as fp:
121
+ fp.write('xbot')
122
+ with sftpconn.open(p, 'r') as fp:
123
+ assert fp.read().decode('utf-8') == 'xbot'
124
+ ```
125
+
126
+ ## 示例项目
127
+
128
+ 展示如何在一个测试项目中使用本插件的示例:[demo](https://github.com/zhaowcheng/xbot.plugins.ssh/tree/master/demo)
File without changes
@@ -0,0 +1,48 @@
1
+ from typing import Union
2
+
3
+ from xbot.framework import testbed
4
+ from xbot.plugins.ssh.ssh import SSHConnection
5
+ from xbot.plugins.ssh.sftp import SFTPConnection
6
+
7
+
8
+ class TestBed(testbed.TestBed):
9
+ """
10
+ TestBed for ssh demo.
11
+ """
12
+ def __init__(self, filepath: str):
13
+ """
14
+ :param filepath: testbed filepath.
15
+ """
16
+ super().__init__(filepath)
17
+ self._conns = {
18
+ 'ssh': {},
19
+ 'sftp': {}
20
+ }
21
+
22
+ def get_conn(
23
+ self,
24
+ typ: str,
25
+ role: str
26
+ ) -> Union[SSHConnection, SFTPConnection]:
27
+ """
28
+ Get specific connection to the specified role.
29
+
30
+ :param typ: connection type, 'ssh' or 'sftp'.
31
+ :param role: user role.
32
+ """
33
+ typs = ('ssh', 'sftp')
34
+ if typ not in typs:
35
+ raise ValueError(f'Invalid connection type: {typ}, should be one of {typs}.')
36
+ for user in self.get('host.users'):
37
+ if user['role'] == role:
38
+ if role not in self._conns[typ]:
39
+ conn = SSHConnection() if typ == 'ssh' else SFTPConnection()
40
+ conn.connect(self.get('host.ip'),
41
+ user['name'],
42
+ user['password'],
43
+ port=self.get('host.sshport'))
44
+ self._conns[typ][role] = conn
45
+ return self._conns[typ][role]
46
+ raise ValueError(f'No such user: role={role}')
47
+
48
+
@@ -0,0 +1,15 @@
1
+ from xbot.framework import testcase
2
+
3
+ from .testbed import TestBed
4
+
5
+
6
+ class TestCase(testcase.TestCase):
7
+ """
8
+ TestCase for ssh demo.
9
+ """
10
+ @property
11
+ def testbed(self) -> TestBed:
12
+ """
13
+ TestBed instance.
14
+ """
15
+ return self.__testbed
File without changes